diff --git a/pkg/tiller/release_server.go b/pkg/tiller/release_server.go
index 68169fe899e17c8f26841bb79a6de9c416e75ca1..900a5236581de200de44eff6a52e301bbdf24c2c 100644
--- a/pkg/tiller/release_server.go
+++ b/pkg/tiller/release_server.go
@@ -65,6 +65,8 @@ var (
 	errInvalidRevision = errors.New("invalid release revision")
 	//errInvalidName indicates that an invalid release name was provided
 	errInvalidName = errors.New("invalid release name, must match regex ^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])+$ and the length must not be longer than 53")
+	// errPending indicates that Tiller is already applying an operation on a release
+	errPending = errors.New("another operation (install/upgrade/rollback) is in progress")
 )
 
 // ListDefaultLimit is the default limit for number of items returned in a list.
diff --git a/pkg/tiller/release_update.go b/pkg/tiller/release_update.go
index 5fb1552bff1d78bbff4fe960662ef27721374564..c9ac8733411de3164ed518fb3047e320730f1f8d 100644
--- a/pkg/tiller/release_update.go
+++ b/pkg/tiller/release_update.go
@@ -93,6 +93,14 @@ func (s *ReleaseServer) prepareUpdate(req *services.UpdateReleaseRequest) (*rele
 		return nil, nil, err
 	}
 
+	// Concurrent `helm upgrade`s will either fail here with `errPending` or
+	// when creating the release with "already exists". This should act as a
+	// pessimistic lock.
+	sc := lastRelease.Info.Status.Code
+	if sc == release.Status_PENDING_INSTALL || sc == release.Status_PENDING_UPGRADE || sc == release.Status_PENDING_ROLLBACK {
+		return nil, nil, errPending
+	}
+
 	// Increment revision count. This is passed to templates, and also stored on
 	// the release object.
 	revision := lastRelease.Version + 1
diff --git a/pkg/tiller/release_update_test.go b/pkg/tiller/release_update_test.go
index a626295c2378b085c4a30134dddb453063de38d2..0346ba18091684d2b75e6ae603ad5da578c3b430 100644
--- a/pkg/tiller/release_update_test.go
+++ b/pkg/tiller/release_update_test.go
@@ -104,6 +104,31 @@ func TestUpdateRelease(t *testing.T) {
 		t.Errorf("Expected description %q, got %q", edesc, got)
 	}
 }
+func TestUpdateReleasePendingError(t *testing.T) {
+	c := helm.NewContext()
+	rs := rsFixture()
+	rel := releaseStub()
+	rs.env.Releases.Create(rel)
+	rel2 := releaseStub()
+	rel2.Info.Status.Code = release.Status_PENDING_UPGRADE
+	rel2.Version = 2
+	rs.env.Releases.Create(rel2)
+
+	req := &services.UpdateReleaseRequest{
+		Name: rel.Name,
+		Chart: &chart.Chart{
+			Metadata: &chart.Metadata{Name: "hello"},
+			Templates: []*chart.Template{
+				{Name: "templates/hello", Data: []byte("hello: world")},
+				{Name: "templates/hooks", Data: []byte(manifestWithUpgradeHooks)},
+			},
+		},
+	}
+	_, err := rs.UpdateRelease(c, req)
+	if err == nil {
+		t.Fatalf("Expected failure to update")
+	}
+}
 func TestUpdateRelease_ResetValues(t *testing.T) {
 	c := helm.NewContext()
 	rs := rsFixture()