diff --git a/cmd/helm/upgrade.go b/cmd/helm/upgrade.go
index ca60c9985df0f0dd5c3ce21829a2e75506edb757..b91efbbc642dc9724c6de1cce06fe354011d6438 100644
--- a/cmd/helm/upgrade.go
+++ b/cmd/helm/upgrade.go
@@ -21,10 +21,12 @@ import (
 	"fmt"
 	"io"
 	"io/ioutil"
+	"strings"
 
 	"github.com/spf13/cobra"
 
 	"k8s.io/helm/pkg/helm"
+	"k8s.io/helm/pkg/storage/driver"
 )
 
 const upgradeDesc = `
@@ -48,6 +50,8 @@ type upgradeCmd struct {
 	values       *values
 	verify       bool
 	keyring      string
+	install      bool
+	namespace    string
 }
 
 func newUpgradeCmd(client helm.Interface, out io.Writer) *cobra.Command {
@@ -83,41 +87,45 @@ func newUpgradeCmd(client helm.Interface, out io.Writer) *cobra.Command {
 	f.BoolVar(&upgrade.disableHooks, "disable-hooks", false, "disable pre/post upgrade hooks")
 	f.BoolVar(&upgrade.verify, "verify", false, "verify the provenance of the chart before upgrading")
 	f.StringVar(&upgrade.keyring, "keyring", defaultKeyring(), "the path to the keyring that contains public singing keys")
+	f.BoolVarP(&upgrade.install, "install", "i", false, "if a release by this name doesn't already exist, run an install")
+	f.StringVar(&upgrade.namespace, "namespace", "default", "the namespace to install the release into (only used if --install is set)")
 
 	return cmd
 }
 
-func (u *upgradeCmd) vals() ([]byte, error) {
-	var buffer bytes.Buffer
-
-	// User specified a values file via -f/--values
-	if u.valuesFile != "" {
-		bytes, err := ioutil.ReadFile(u.valuesFile)
-		if err != nil {
-			return []byte{}, err
-		}
-		buffer.Write(bytes)
-	}
-
-	// User specified value pairs via --set
-	// These override any values in the specified file
-	if len(u.values.pairs) > 0 {
-		bytes, err := u.values.yaml()
-		if err != nil {
-			return []byte{}, err
-		}
-		buffer.Write(bytes)
-	}
-
-	return buffer.Bytes(), nil
-}
-
 func (u *upgradeCmd) run() error {
 	chartPath, err := locateChartPath(u.chart, u.verify, u.keyring)
 	if err != nil {
 		return err
 	}
 
+	if u.install {
+		// If a release does not exist, install it. If another error occurs during
+		// the check, ignore the error and continue with the upgrade.
+		//
+		// The returned error is a grpc.rpcError that wraps the message from the original error.
+		// So we're stuck doing string matching against the wrapped error, which is nested somewhere
+		// inside of the grpc.rpcError message.
+		_, err := u.client.ReleaseContent(u.release, helm.ContentReleaseVersion(1))
+		if err != nil && strings.Contains(err.Error(), driver.ErrReleaseNotFound.Error()) {
+			fmt.Fprintf(u.out, "Release %q does not exist. Installing it now.\n", u.release)
+			ic := &installCmd{
+				chartPath:    chartPath,
+				client:       u.client,
+				out:          u.out,
+				name:         u.release,
+				valuesFile:   u.valuesFile,
+				dryRun:       u.dryRun,
+				verify:       u.verify,
+				disableHooks: u.disableHooks,
+				keyring:      u.keyring,
+				values:       u.values,
+				namespace:    u.namespace,
+			}
+			return ic.run()
+		}
+	}
+
 	rawVals, err := u.vals()
 	if err != nil {
 		return err
@@ -139,5 +147,29 @@ func (u *upgradeCmd) run() error {
 	PrintStatus(u.out, status)
 
 	return nil
+}
+
+func (u *upgradeCmd) vals() ([]byte, error) {
+	var buffer bytes.Buffer
+
+	// User specified a values file via -f/--values
+	if u.valuesFile != "" {
+		bytes, err := ioutil.ReadFile(u.valuesFile)
+		if err != nil {
+			return []byte{}, err
+		}
+		buffer.Write(bytes)
+	}
 
+	// User specified value pairs via --set
+	// These override any values in the specified file
+	if len(u.values.pairs) > 0 {
+		bytes, err := u.values.yaml()
+		if err != nil {
+			return []byte{}, err
+		}
+		buffer.Write(bytes)
+	}
+
+	return buffer.Bytes(), nil
 }
diff --git a/cmd/helm/upgrade_test.go b/cmd/helm/upgrade_test.go
index f51049e28388220ff9455cdda40188f6e62070e5..7eab8acde375304c63b2a5ceaf9c1a55526ff6e9 100644
--- a/cmd/helm/upgrade_test.go
+++ b/cmd/helm/upgrade_test.go
@@ -69,6 +69,13 @@ func TestUpgradeCmd(t *testing.T) {
 			resp:     releaseMock(&releaseOptions{name: "funny-bunny", version: 2, chart: ch}),
 			expected: "funny-bunny has been upgraded. Happy Helming!\n",
 		},
+		{
+			name:     "install a release with 'upgrade --install'",
+			args:     []string{"zany-bunny", chartPath},
+			flags:    []string{"-i"},
+			resp:     releaseMock(&releaseOptions{name: "zany-bunny", version: 1, chart: ch}),
+			expected: "zany-bunny has been upgraded. Happy Helming!\n",
+		},
 	}
 
 	cmd := func(c *fakeReleaseClient, out io.Writer) *cobra.Command {