diff --git a/core/lib/Drupal/Core/Plugin/Discovery/AlterDecorator.php b/core/lib/Drupal/Core/Plugin/Discovery/AlterDecorator.php
new file mode 100644
index 0000000..d4ce40b
--- /dev/null
+++ b/core/lib/Drupal/Core/Plugin/Discovery/AlterDecorator.php
@@ -0,0 +1,69 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\Core\Plugin\Discovery\AlterDiscoveryDecorator.
+*/
+
+namespace Drupal\Core\Plugin\Discovery;
+
+use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
+
+/**
+ * Enables altering of discovered plugin definitions.
+ */
+class AlterDecorator implements DiscoveryInterface {
+  /**
+   * The name of the alter hook that will be implemented by this discovery instance.
+   *
+   * @var string
+   */
+  protected $hook;
+
+  /**
+   * The Discovery object being decorated.
+   *
+   * @var Drupal\Component\Plugin\Discovery\DiscoveryInterface
+   */
+  protected $decorated;
+
+  /**
+   * Constructs a Drupal\Core\Plugin\Discovery\AlterDecorator object.
+   *
+   * It uses the DiscoveryInterface object it should decorate.
+   *
+   * @param Drupal\Component\Plugin\Discovery\DiscoveryInterface $decorated
+   *   The object implementing DiscoveryInterface that is being decorated.
+   * @param string $hook
+   *   The name of the alter hook that will be implemented by this discovery instance.
+   */
+  public function __construct(DiscoveryInterface $decorated, $hook) {
+    $this->decorated = $decorated;
+    $this->hook = $hook;
+  }
+
+  /**
+   * Implements Drupal\Component\Plugin\Discovery\DiscoveryInterface::getDefinition().
+   */
+  public function getDefinition($plugin_id) {
+    $definitions = $this->getDefinitions();
+    return isset($definitions[$plugin_id]) ? $definitions[$plugin_id] : NULL;
+  }
+
+
+  /**
+   * Implements Drupal\Component\Plugin\Discovery\DiscoveryInterface::getDefinitions().
+   */
+  public function getDefinitions() {
+    $definitions = $this->decorated->getDefinitions();
+    drupal_alter($this->hook, $definitions);
+    return $definitions;
+  }
+
+  /**
+   * Passes through all unknown calls onto the decorated object.
+   */
+  public function __call($method, $args) {
+    return call_user_func_array(array($this->decorated, $method), $args);
+  }
+}
diff --git a/core/lib/Drupal/Core/Plugin/Discovery/HookDiscovery.php b/core/lib/Drupal/Core/Plugin/Discovery/HookDiscovery.php
index 3ff05f9..9a35498 100644
--- a/core/lib/Drupal/Core/Plugin/Discovery/HookDiscovery.php
+++ b/core/lib/Drupal/Core/Plugin/Discovery/HookDiscovery.php
@@ -51,7 +51,6 @@ class HookDiscovery implements DiscoveryInterface {
         $definitions[$plugin_id] = $definition;
       }
     }
-    drupal_alter($this->hook, $definitions);
     return $definitions;
   }
 }
diff --git a/core/modules/system/lib/Drupal/system/Tests/Plugin/AlterDecoratorTest.php b/core/modules/system/lib/Drupal/system/Tests/Plugin/AlterDecoratorTest.php
new file mode 100644
index 0000000..a8030e9
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Tests/Plugin/AlterDecoratorTest.php
@@ -0,0 +1,65 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\system\Tests\Plugin\AlterDecoratorTest.
+ */
+
+namespace Drupal\system\Tests\Plugin;
+
+use Drupal\Component\Plugin\Exception\ExceptionInterface;
+use Exception;
+use Drupal\plugin_test\Plugin\AlterDecoratorTestPluginManager;
+use Drupal\plugin_test\Plugin\TestPluginManager;
+use Drupal\simpletest\WebTestBase;
+
+/**
+ * Tests that the AlterDecorator fires and respects the alter hook.
+ */
+class AlterDecoratorTest extends WebTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('plugin_test');
+
+  /**
+   * Stores a plugin manager which uses the AlterDecorator.
+   *
+   * @var Drupal\plugin_test\Plugin\AlterDecoratorTestPluginManager;
+   */
+  protected $alterTestPluginManager;
+
+  public static function getInfo() {
+    return array(
+      'name' => 'AlterDecorator',
+      'description' => 'Tests that the AlterDecorator fires and respects the alter hook.',
+      'group' => 'Plugin API',
+    );
+  }
+
+  public function setUp() {
+    parent::setUp();
+
+    // Setup a plugin manager which uses the alter decorator.
+    $this->alterTestPluginManager = new AlterDecoratorTestPluginManager();
+  }
+
+  /**
+   * Tests getDefinitions() and getDefinition() of Drupal\Core\Plugin\Discovery\AlterDecorator.
+   */
+  public function testAlterDecorator() {
+    // Ensure that getDefinitions() fires and changes the actual plugin definitions.
+    $definitions = $this->alterTestPluginManager->getDefinitions();
+    foreach ($definitions as &$definition) {
+      $this->assertTrue($definition['altered']);
+    }
+
+    // Ensure that getDefinitions() fires and changes the actual plugin definition.
+    $definition = $this->alterTestPluginManager->getDefinition('user_login');
+    $this->assertTrue($definition['altered_single']);
+  }
+
+}
diff --git a/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/AlterDecoratorTestPluginManager.php b/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/AlterDecoratorTestPluginManager.php
new file mode 100644
index 0000000..2168b8b
--- /dev/null
+++ b/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/AlterDecoratorTestPluginManager.php
@@ -0,0 +1,20 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\plugin_test\Plugin\plugin_test\AlterDecoratorTestPluginManager.
+ */
+
+namespace Drupal\plugin_test\Plugin;
+
+use Drupal\Core\Plugin\Discovery\AlterDecorator;
+
+/**
+ * Defines a plugin manager used by AlterDecorator unit tests.
+ */
+class AlterDecoratorTestPluginManager extends TestPluginManager {
+  public function __construct() {
+    parent::__construct();
+    $this->discovery = new AlterDecorator($this->discovery, 'plugin_test');
+  }
+}
diff --git a/core/modules/system/tests/modules/plugin_test/plugin_test.module b/core/modules/system/tests/modules/plugin_test/plugin_test.module
index dc6986d..147e052 100644
--- a/core/modules/system/tests/modules/plugin_test/plugin_test.module
+++ b/core/modules/system/tests/modules/plugin_test/plugin_test.module
@@ -4,3 +4,13 @@
  * @file
  * Helper module for the plugin tests.
  */
+
+/**
+ * Implements hook_plugin_test_alter().
+ */
+function plugin_test_plugin_test_alter(&$definitions) {
+  foreach ($definitions as &$definition) {
+    $definition['altered'] = TRUE;
+  }
+  $definitions['user_login']['altered_single'] = TRUE;
+}
