diff --git a/lib/src/command/global.dart b/lib/src/command/global.dart
index cfd2996f2616dd43ce0cf45785ed2b6a89bf73ff..aa1ee2493d4ec33d775f0d66623614bc23c8a79d 100644
--- a/lib/src/command/global.dart
+++ b/lib/src/command/global.dart
@@ -6,6 +6,7 @@ library pub.command.global;
 
 import '../command.dart';
 import 'global_activate.dart';
+import 'global_deactivate.dart';
 
 /// Handles the `global` pub command.
 class GlobalCommand extends PubCommand {
@@ -13,6 +14,7 @@ class GlobalCommand extends PubCommand {
   String get usage => "pub global <subcommand>";
 
   final subcommands = {
-    "activate": new GlobalActivateCommand()
+    "activate": new GlobalActivateCommand(),
+    "deactivate": new GlobalDeactivateCommand()
   };
 }
diff --git a/lib/src/command/global_deactivate.dart b/lib/src/command/global_deactivate.dart
new file mode 100644
index 0000000000000000000000000000000000000000..047067aae30bbad80fc61125b39a332496d84da4
--- /dev/null
+++ b/lib/src/command/global_deactivate.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library pub.command.global_deactivate;
+
+import 'dart:async';
+
+import '../command.dart';
+import '../utils.dart';
+import '../version.dart';
+
+/// Handles the `global deactivate` pub command.
+class GlobalDeactivateCommand extends PubCommand {
+  String get description => "Remove a previously activated package.";
+  String get usage => "pub global deactivate <package>";
+  bool get requiresEntrypoint => false;
+  bool get takesArguments => true;
+
+  Future onRun() {
+    // Make sure there is a package.
+    if (commandOptions.rest.isEmpty) {
+      usageError("No package to deactivate given.");
+    }
+
+    // Don't allow extra arguments.
+    if (commandOptions.rest.length > 1) {
+      var unexpected = commandOptions.rest.skip(1).map((arg) => '"$arg"');
+      var arguments = pluralize("argument", unexpected.length);
+      usageError("Unexpected $arguments ${toSentence(unexpected)}.");
+    }
+
+    globals.deactivate(commandOptions.rest.first);
+  }
+}
diff --git a/lib/src/global_packages.dart b/lib/src/global_packages.dart
index c0ab46f8e23d315b090b3b5214f6919ad29777c1..eb4864f0fc8f75b6f0d796cce2a631748d929a2f 100644
--- a/lib/src/global_packages.dart
+++ b/lib/src/global_packages.dart
@@ -5,9 +5,10 @@
 library pub.global_packages;
 
 import 'dart:async';
+import 'dart:convert';
 import 'dart:io';
 
-import 'package:path/path.dart' as path;
+import 'package:path/path.dart' as p;
 
 import 'io.dart';
 import 'lock_file.dart';
@@ -33,7 +34,7 @@ class GlobalPackages {
   final SystemCache cache;
 
   /// The directory where the lockfiles for activated packages are stored.
-  String get _directory => path.join(cache.rootDir, "global_packages");
+  String get _directory => p.join(cache.rootDir, "global_packages");
 
   /// The source that global packages can be activated from.
   // TODO(rnystrom): Allow activating packages from other sources.
@@ -49,7 +50,7 @@ class GlobalPackages {
   /// Finds the latest version of the hosted package with [name] that matches
   /// [constraint] and makes it the active global version.
   Future activate(String name, VersionConstraint constraint) {
-    var lockFilePath = path.join(_directory, name + ".lock");
+    var lockFilePath = p.join(_directory, name + ".lock");
 
     // See if we already have it activated.
     var lockFile;
@@ -106,6 +107,22 @@ class GlobalPackages {
     });
   }
 
+  /// Deactivates a previously-activated package named [name] or fails with
+  /// an error if [name] is not an active package.
+  void deactivate(String name) {
+    // See if we already have it activated.
+    try {
+      var lockFilePath = p.join(_directory, "$name.lock");
+      var lockFile = new LockFile.load(lockFilePath, cache.sources);
+      var version = lockFile.packages[name].version;
+
+      deleteEntry(lockFilePath);
+      log.message("Deactivated package ${log.bold(name)} $version.");
+    } on IOException catch (error) {
+      dataError("No active package ${log.bold(name)}.");
+    }
+  }
+
   /// Picks the best version of [package] to activate that meets [constraint].
   ///
   /// If [version] is not `null`, this tries to maintain that version if
diff --git a/test/global/activate/unknown_package_test.dart b/test/global/activate/unknown_package_test.dart
index 5348fe849384110376df23af7117c7b5d4ab3069..4a6e3a6dd6317542f52478763db00bc092f62000 100644
--- a/test/global/activate/unknown_package_test.dart
+++ b/test/global/activate/unknown_package_test.dart
@@ -4,6 +4,7 @@
 
 import 'package:scheduled_test/scheduled_test.dart';
 
+import '../../../lib/src/exit_codes.dart' as exit_codes;
 import '../../descriptor.dart' as d;
 import '../../test_pub.dart';
 
@@ -14,6 +15,6 @@ main() {
 
     schedulePub(args: ["global", "activate", "foo"],
         error: startsWith("Could not find package foo at"),
-        exitCode: 1);
+        exitCode: exit_codes.UNAVAILABLE);
   });
 }
diff --git a/test/global/deactivate/deactivate_and_reactivate_package_test.dart b/test/global/deactivate/deactivate_and_reactivate_package_test.dart
new file mode 100644
index 0000000000000000000000000000000000000000..0e04d187419cbe0e6e613de60c9227b2b7eea597
--- /dev/null
+++ b/test/global/deactivate/deactivate_and_reactivate_package_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:scheduled_test/scheduled_test.dart';
+
+import '../../../lib/src/exit_codes.dart' as exit_codes;
+import '../../descriptor.dart' as d;
+import '../../test_pub.dart';
+
+main() {
+  initConfig();
+  integration('activates a different version after deactivating', () {
+    servePackages([
+      packageMap("foo", "1.0.0"),
+      packageMap("foo", "2.0.0")
+    ]);
+
+    // Activate an old version.
+    schedulePub(args: ["global", "activate", "foo", "1.0.0"]);
+
+    schedulePub(args: ["global", "deactivate", "foo"],
+        output: "Deactivated package foo 1.0.0.");
+
+    // Activating again should forget the old version.
+    schedulePub(args: ["global", "activate", "foo"], output: """
+Downloading foo 2.0.0...
+Resolving dependencies...
+Activated foo 2.0.0.
+    """);
+  });
+}
diff --git a/test/global/deactivate/deactivate_package_test.dart b/test/global/deactivate/deactivate_package_test.dart
new file mode 100644
index 0000000000000000000000000000000000000000..f6e9056422b46b34bed4048316f6f2f94124074d
--- /dev/null
+++ b/test/global/deactivate/deactivate_package_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:scheduled_test/scheduled_test.dart';
+
+import '../../../lib/src/exit_codes.dart' as exit_codes;
+import '../../descriptor.dart' as d;
+import '../../test_pub.dart';
+
+main() {
+  initConfig();
+  integration('deactivates an active package', () {
+    servePackages([
+      packageMap("foo", "1.0.0")
+    ]);
+
+    schedulePub(args: ["global", "activate", "foo"]);
+
+    schedulePub(args: ["global", "deactivate", "foo"],
+        output: "Deactivated package foo 1.0.0.");
+  });
+}
diff --git a/test/global/deactivate/missing_package_arg_test.dart b/test/global/deactivate/missing_package_arg_test.dart
new file mode 100644
index 0000000000000000000000000000000000000000..33a2a1b86e8c7b5acb7e5a273f99ec34fb696ca5
--- /dev/null
+++ b/test/global/deactivate/missing_package_arg_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import '../../../lib/src/exit_codes.dart' as exit_codes;
+import '../../test_pub.dart';
+
+main() {
+  initConfig();
+  integration('fails if no package was given', () {
+    schedulePub(args: ["global", "deactivate"],
+        error: """
+            No package to deactivate given.
+
+            Usage: pub global deactivate <package>
+            -h, --help    Print usage information for this command.
+            """,
+        exitCode: exit_codes.USAGE);
+  });
+}
diff --git a/test/global/deactivate/unexpected_arguments_test.dart b/test/global/deactivate/unexpected_arguments_test.dart
new file mode 100644
index 0000000000000000000000000000000000000000..9057ebf24c32ac76801ea16a5eda7ef0476e5d9c
--- /dev/null
+++ b/test/global/deactivate/unexpected_arguments_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import '../../../lib/src/exit_codes.dart' as exit_codes;
+import '../../test_pub.dart';
+
+main() {
+  initConfig();
+  integration('fails if there are extra arguments', () {
+    schedulePub(args: ["global", "deactivate", "foo", "bar", "baz"],
+        error: """
+            Unexpected arguments "bar" and "baz".
+
+            Usage: pub global deactivate <package>
+            -h, --help    Print usage information for this command.
+            """,
+        exitCode: exit_codes.USAGE);
+  });
+}
diff --git a/test/global/deactivate/unknown_package_test.dart b/test/global/deactivate/unknown_package_test.dart
new file mode 100644
index 0000000000000000000000000000000000000000..3860c48023c6a04ac6e147f5832370466aff6c07
--- /dev/null
+++ b/test/global/deactivate/unknown_package_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:scheduled_test/scheduled_test.dart';
+
+import '../../../lib/src/exit_codes.dart' as exit_codes;
+import '../../descriptor.dart' as d;
+import '../../test_pub.dart';
+
+main() {
+  initConfig();
+  integration('errors if the package is not activated', () {
+    servePackages([]);
+
+    schedulePub(args: ["global", "deactivate", "foo"],
+        error: "No active package foo.",
+        exitCode: exit_codes.DATA);
+  });
+}