diff --git a/core/lib/Drupal/Core/Plugin/Discovery/YamlDiscovery.php b/core/lib/Drupal/Core/Plugin/Discovery/YamlDiscovery.php
new file mode 100644
index 0000000..516704b
--- /dev/null
+++ b/core/lib/Drupal/Core/Plugin/Discovery/YamlDiscovery.php
@@ -0,0 +1,65 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Plugin\Discovery\YamlDiscovery.
+ */
+
+namespace Drupal\Core\Plugin\Discovery;
+
+use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
+use Drupal\Component\Discovery\YamlDiscovery as ComponentYamlDiscovery;
+
+/**
+ * Allows YAML files to define plugin definitions.
+ */
+class YamlDiscovery implements DiscoveryInterface {
+
+  /**
+   * YAML file discovery and parsing handler.
+   *
+   * @var \Drupal\Component\Discovery\YamlDiscovery
+   */
+  protected $discovery;
+
+  /**
+   * Construct a YamlDiscovery object.
+   *
+   * @param string $name
+   *   The file name suffix to use for discovery. E.g. 'test' will become
+   *   'MODULE.test.yml'.
+   * @param array $directories
+   *   An array of directories to scan.
+   */
+  function __construct($name, array $directories) {
+    $this->discovery = new ComponentYamlDiscovery($name, $directories);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getDefinition($plugin_id) {
+    $definitions = $this->getDefinitions();
+    return isset($definitions[$plugin_id]) ? $definitions[$plugin_id] : NULL;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getDefinitions() {
+    $plugins = $this->discovery->findAll();
+
+    // Flatten definitions into what's expected from plugins.
+    $definitions = array();
+    foreach ($plugins as $provider => $list) {
+      foreach ($list as $id => $definition) {
+        $definitions[$id] = $definition + array(
+          'provider' => $provider,
+          'id' => $id,
+        );
+      }
+    }
+
+    return $definitions;
+  }
+}
diff --git a/core/lib/Drupal/Core/Plugin/Discovery/YamlDiscoveryDecorator.php b/core/lib/Drupal/Core/Plugin/Discovery/YamlDiscoveryDecorator.php
new file mode 100644
index 0000000..eb63ea2
--- /dev/null
+++ b/core/lib/Drupal/Core/Plugin/Discovery/YamlDiscoveryDecorator.php
@@ -0,0 +1,53 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Plugin\Discovery\YamlDiscoveryDecorator.
+ */
+
+namespace Drupal\Core\Plugin\Discovery;
+
+/**
+ * Enables YAML discovery for plugin definitions.
+ */
+class YamlDiscoveryDecorator extends YamlDiscovery {
+
+  /**
+   * The Discovery object being decorated.
+   *
+   * @var \Drupal\Component\Plugin\Discovery\DiscoveryInterface
+   */
+  protected $decorated;
+
+  /**
+   * Constructs a YamlDiscoveryDecorator object.
+   *
+   * @param \Drupal\Component\Plugin\Discovery\DiscoveryInterface $decorated
+   *   The discovery object that is being decorated.
+   * @param string $name
+   *   The file name suffix to use for discovery. E.g. 'test' will become
+   *   'MODULE.test.yml'.
+   * @param array $directories
+   *   An array of directories to scan.
+   */
+  public function __construct(DiscoveryInterface $decorated, $name, array $directories) {
+    parent::__construct($name, $directories);
+
+    $this->decorated = $decorated;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getDefinitions() {
+    return parent::getDefinitions() + $this->decorated->getDefinitions();
+  }
+
+  /**
+   * 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/tests/Drupal/Tests/Core/Plugin/Discovery/Fixtures/test_1/test_1.test.yml b/core/tests/Drupal/Tests/Core/Plugin/Discovery/Fixtures/test_1/test_1.test.yml
new file mode 100644
index 0000000..e23d2f0
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Plugin/Discovery/Fixtures/test_1/test_1.test.yml
@@ -0,0 +1,5 @@
+test_1_a:
+  name: test
+test_1_b:
+  name : test
+  provider: another_provider_1
diff --git a/core/tests/Drupal/Tests/Core/Plugin/Discovery/Fixtures/test_2/test_2.test.yml b/core/tests/Drupal/Tests/Core/Plugin/Discovery/Fixtures/test_2/test_2.test.yml
new file mode 100644
index 0000000..9004723
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Plugin/Discovery/Fixtures/test_2/test_2.test.yml
@@ -0,0 +1,5 @@
+test_2_a:
+  name: test
+  provider: another_provider_2
+test_2_b:
+  name: test
diff --git a/core/tests/Drupal/Tests/Core/Plugin/Discovery/YamlDiscoveryTest.php b/core/tests/Drupal/Tests/Core/Plugin/Discovery/YamlDiscoveryTest.php
new file mode 100644
index 0000000..6d15128
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Plugin/Discovery/YamlDiscoveryTest.php
@@ -0,0 +1,93 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\Core\Plugin\Discovery\YamlDiscoveryTest.
+ */
+
+namespace Drupal\Tests\Core\Plugin\Discovery;
+
+use Drupal\Tests\UnitTestCase;
+use Drupal\Core\Plugin\Discovery\YamlDiscovery;
+
+/**
+ * Tests plugin YAML discovery.
+ *
+ * @see \Drupal\Core\Plugin\Discovery\YamlDiscovery
+ */
+class YamlDiscoveryTest extends UnitTestCase {
+
+  /**
+   * The YamlDiscovery instance to test.
+   *
+   * @var \Drupal\Core\Plugin\Discovery\YamlDiscovery
+   */
+  protected $discovery;
+
+  /**
+   * Expected provider => key mappings for testing.
+   *
+   * @var array
+   */
+  protected $expectedKeys = array(
+    'test_1' => 'test_1_a',
+    'another_provider_1' => 'test_1_b',
+    'another_provider_2' => 'test_2_a',
+    'test_2' => 'test_2_b',
+  );
+
+  public static function getInfo() {
+    return array(
+      'name' => 'YamlDiscovery',
+      'description' => 'YamlDiscovery unit tests.',
+      'group' => 'Plugin',
+    );
+  }
+
+  public function setUp() {
+    parent::setUp();
+
+    $base_path = __DIR__ . '/Fixtures';
+    // Set up the directories to search.
+    $directories = array(
+      'test_1' => $base_path . '/test_1',
+      'test_2' => $base_path . '/test_2',
+    );
+
+    $this->discovery = new YamlDiscovery('test', $directories);
+  }
+
+  /**
+   * Tests the getDefinitions() method.
+   */
+  public function testGetDefinitions() {
+    $definitions = $this->discovery->getDefinitions();
+
+    $this->assertInternalType('array', $definitions);
+    $this->assertCount(4, $definitions);
+
+    foreach ($this->expectedKeys as $expected_key) {
+      $this->assertArrayHasKey($expected_key, $definitions);
+    }
+
+    foreach ($definitions as $id => $definition) {
+      foreach (array('name', 'id', 'provider') as $key) {
+        $this->assertArrayHasKey($key, $definition);
+      }
+      $this->assertEquals($id, $definition['id']);
+      $this->assertEquals(array_search($id, $this->expectedKeys), $definition['provider']);
+    }
+  }
+
+  /**
+   * Tests the getDefinition() method.
+   */
+  public function testGetDefinition() {
+    $definitions = $this->discovery->getDefinitions();
+    // Test the getDefinition() method.
+    foreach ($this->expectedKeys as $expected_key) {
+      $this->assertEquals($definitions[$expected_key], $this->discovery->getDefinition($expected_key));
+    }
+  }
+
+}
