diff --git a/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php b/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php
index e9c4ce9..bf6e6ec 100644
--- a/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php
+++ b/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php
@@ -8,6 +8,7 @@
 namespace Drupal\Core\Plugin;
 
 use Drupal\Component\Plugin\Discovery\CachedDiscoveryInterface;
+use Drupal\Component\Plugin\Exception\PluginException;
 use Drupal\Core\Plugin\Discovery\ContainerDerivativeDiscoveryDecorator;
 use Drupal\Component\Plugin\PluginManagerBase;
 use Drupal\Component\Plugin\PluginManagerInterface;
@@ -99,6 +100,13 @@ class DefaultPluginManager extends PluginManagerBase implements PluginManagerInt
   protected $defaults = array();
 
   /**
+   * Defines a fallback ID in case the plugin instance could not be created.
+   *
+   * @var string
+   */
+  protected $fallbackPluginId;
+
+  /**
    * Creates the discovery object.
    *
    * @param string|bool $subdir
@@ -162,6 +170,16 @@ protected function alterInfo($alter_hook) {
   }
 
   /**
+   * Sets the fallback plugin ID.
+   *
+   * @param string $fallback_plugin_id
+   *   The plugin ID to be falled back to.
+   */
+  public function setFallbackPluginId($fallback_plugin_id) {
+    $this->fallbackPluginId = $fallback_plugin_id;
+  }
+
+  /**
    * {@inheritdoc}
    */
   public function getDefinition($plugin_id) {
@@ -277,4 +295,40 @@ protected function findDefinitions() {
     return $definitions;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function createInstance($plugin_id, array $configuration = array()) {
+    try {
+      $instance = $this->factory->createInstance($plugin_id, $configuration);
+    }
+    catch (PluginException $exception) {
+      if ($fallback_plugin_id = $this->getFallbackPluginId($plugin_id, $configuration)) {
+        // Allow implementations show the exception message.
+        $configuration['_exception'] = $exception;
+        $instance = $this->factory->createInstance($this->getFallbackPluginId($plugin_id, $configuration), $configuration);
+      }
+      else {
+        throw $exception;
+      }
+    }
+    return $instance;
+  }
+
+  /**
+   * Returns the fallback plugin ID to be used.
+   *
+   * @param string $original_plugin_id
+   *   The plugin ID of the non-instantiable plugin.
+   * @param array $configuration
+   *   The original configuration of the plugin.
+   *
+   * @return string|null
+   *   The plugin ID of the fallback instance or NULL if there is no fallback
+   *   set.
+   */
+  protected function getFallbackPluginId($original_plugin_id, array $configuration) {
+    return $this->fallbackPluginId;
+  }
+
 }
diff --git a/core/modules/views/lib/Drupal/views/Plugin/ViewsHandlerManager.php b/core/modules/views/lib/Drupal/views/Plugin/ViewsHandlerManager.php
index 3e6ec05..e833fac 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/ViewsHandlerManager.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/ViewsHandlerManager.php
@@ -12,6 +12,7 @@
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Language\LanguageManagerInterface;
 use Drupal\Core\Plugin\DefaultPluginManager;
+use Drupal\views\Plugin\views\HandlerBase;
 use Drupal\views\ViewsData;
 use Symfony\Component\DependencyInjection\Container;
 
@@ -58,6 +59,7 @@ public function __construct($handler_type, \Traversable $namespaces, ViewsData $
     parent::__construct("Plugin/views/$handler_type", $namespaces, $module_handler, $plugin_definition_annotation_name);
 
     $this->setCacheBackend($cache_backend, $language_manager, "views:$handler_type", array('extension' => array(TRUE, 'views')));
+    $this->setFallbackPluginId('broken');
 
     $this->viewsData = $views_data;
     $this->handlerType = $handler_type;
@@ -104,30 +106,26 @@ public function getHandler($item, $override = NULL) {
           }
         }
       }
-
-      // @todo This is crazy. Find a way to remove the override functionality.
-      $plugin_id = $override ? : $definition['id'];
-      // Try to use the overridden handler.
-      try {
-        return $this->createInstance($plugin_id, $definition);
-      }
-      catch (PluginException $e) {
-        // If that fails, use the original handler.
-        try {
-          return $this->createInstance($definition['id'], $definition);
-        }
-        catch (PluginException $e) {
-          // Deliberately empty, this case is handled generically below.
-        }
-      }
     }
-
-    if (!$optional) {
-      // debug(t("Missing handler: @table @field @type", array('@table' => $table, '@field' => $field, '@type' => $this->handlerType)));
+    else {
+      $definition = $item;
+      $definition['id'] = 'non_existing';
     }
 
-    // Finally, use the 'broken' handler.
-    return $this->createInstance('broken', array('optional' => $optional, 'original_configuration' => $item));
+    // @todo This is crazy. Find a way to remove the override functionality.
+    $plugin_id = $override ? : $definition['id'];
+    // Try to use the overridden handler.
+    try {
+      return $this->createInstance($plugin_id, $definition);
+    }
+    catch (PluginException $e) {
+      // If that fails, use the original handler / or the broken fallback.
+      $this->setFallbackPluginId('broken');
+      $definition['optional'] = $optional;
+      $result = $this->createInstance($definition['id'], $definition);
+      $this->setFallbackPluginId(NULL);
+      return $result;
+    }
   }
 
   /**
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/BrokenHandlerTrait.php b/core/modules/views/lib/Drupal/views/Plugin/views/BrokenHandlerTrait.php
index e1623f7..9fc5b68 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/BrokenHandlerTrait.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/BrokenHandlerTrait.php
@@ -19,7 +19,7 @@
    */
   public function adminLabel($short = FALSE) {
     $args = array(
-      '@module' => $this->definition['original_configuration']['provider'],
+      '@module' => $this->definition['provider'],
     );
     return $this->isOptional() ? t('Optional handler is missing (Module: @module) …', $args) : t('Broken/missing handler (Module: @module) …', $args);
   }
@@ -64,9 +64,9 @@ public function buildOptionsForm(&$form, &$form_state) {
     }
 
     $items = array(
-      t('Module: @module', array('@module' => $this->definition['original_configuration']['provider'])),
-      t('Table: @table', array('@table' => $this->definition['original_configuration']['table'])),
-      t('Field: @field', array('@field' => $this->definition['original_configuration']['field'])),
+      t('Module: @module', array('@module' => $this->definition['provider'])),
+      t('Table: @table', array('@table' => $this->definition['table'])),
+      t('Field: @field', array('@field' => $this->definition['field'])),
     );
 
     $description_bottom = t('Enabling the appropriate module will may solve this issue. Otherwise, check to see if there is a module update available.');
diff --git a/core/tests/Drupal/Tests/Core/Plugin/DefaultPluginManagerTest.php b/core/tests/Drupal/Tests/Core/Plugin/DefaultPluginManagerTest.php
index 4862ac7..e3cae95 100644
--- a/core/tests/Drupal/Tests/Core/Plugin/DefaultPluginManagerTest.php
+++ b/core/tests/Drupal/Tests/Core/Plugin/DefaultPluginManagerTest.php
@@ -7,13 +7,19 @@
 
 namespace Drupal\Tests\Core\Plugin;
 
+use Drupal\Component\Plugin\Exception\PluginException;
+use Drupal\Component\Plugin\Factory\DefaultFactory;
 use Drupal\Core\Language\Language;
+use Drupal\plugin_test\Plugin\plugin_test\fruit\Apple;
 use Drupal\Tests\UnitTestCase;
 
 /**
  * Tests the DefaultPluginManager.
  *
  * @group Plugin
+ * @group Drupal
+ *
+ * @coversDefaultClass Drupal\Core\Plugin\DefaultPluginManager
  */
 class DefaultPluginManagerTest extends UnitTestCase {
 
@@ -69,6 +75,8 @@ protected function setUp() {
 
   /**
    * Tests the plugin manager with a disabled module.
+   *
+   * @covers ::getDefinition
    */
   public function testDefaultPluginManagerWithDisabledModule() {
      $definitions = $this->expectedDefinitions;
@@ -94,6 +102,9 @@ public function testDefaultPluginManagerWithDisabledModule() {
 
   /**
    * Tests the plugin manager with no cache and altering.
+   *
+   * @covers ::getDefinitions
+   * @covers ::getDefinition
    */
   public function testDefaultPluginManager() {
     $plugin_manager = new TestPluginManager($this->namespaces, $this->expectedDefinitions);
@@ -103,6 +114,9 @@ public function testDefaultPluginManager() {
 
   /**
    * Tests the plugin manager with no cache and altering.
+   *
+   * @covers ::getDefinitions
+   * @covers ::getDefinition
    */
   public function testDefaultPluginManagerWithAlter() {
     $module_handler = $this->getMockBuilder('Drupal\Core\Extension\ModuleHandler')
@@ -123,6 +137,9 @@ public function testDefaultPluginManagerWithAlter() {
 
   /**
    * Tests the plugin manager with caching and altering.
+   *
+   * @covers ::getDefinitions
+   * @covers ::getDefinition
    */
   public function testDefaultPluginManagerWithEmptyCache() {
     $cid = $this->randomName();
@@ -155,6 +172,8 @@ public function testDefaultPluginManagerWithEmptyCache() {
 
   /**
    * Tests the plugin manager with caching and altering.
+   *
+   * @covers ::getDefinitions
    */
   public function testDefaultPluginManagerWithFilledCache() {
     $cid = $this->randomName();
@@ -185,6 +204,9 @@ public function testDefaultPluginManagerWithFilledCache() {
 
   /**
    * Tests the plugin manager cache clear with tags.
+   *
+   * @covers ::getFallbackPluginId
+   * @covers ::createInstance
    */
   public function testCacheClearWithTags() {
     $cid = $this->randomName();
@@ -214,6 +236,46 @@ public function testCacheClearWithTags() {
     $plugin_manager->clearCachedDefinitions();
   }
 
+  /**
+   * Tests the plugin manager without a fallback plugin.
+   *
+   * @expectedException \Drupal\Component\Plugin\Exception\PluginException
+   */
+  public function testCreateInstanceWithoutFallback() {
+    $factory = $this->getMock('\Drupal\Component\Plugin\Factory\FactoryInterface');
+    $factory->expects($this->once())
+      ->method('createInstance')
+      ->with('non_existing', array())
+      ->will($this->throwException(new PluginException()));
+
+    $plugin_manager = new TestPluginManager($this->namespaces, $this->expectedDefinitions, NULL, NULL);
+    $plugin_manager->setFactory($factory);
+    $plugin_manager->createInstance('non_existing');
+  }
+
+  /**
+   * Tests the plugin manager with a fallback plugin.
+   */
+  public function testCreateInstanceWithFallback() {
+    $factory = $this->getMock('\Drupal\Component\Plugin\Factory\FactoryInterface');
+    $apple = new Apple();
+    $exception = new PluginException();
+    $factory->expects($this->at(0))
+      ->method('createInstance')
+      ->with('non_existing', array('key' => 'value'))
+      ->will($this->throwException($exception));
+    $factory->expects($this->at(1))
+      ->method('createInstance')
+      ->with('apple', array('_exception' => $exception, 'key' => 'value'))
+      ->will($this->returnValue($apple));
+
+    $plugin_manager = new TestPluginManager($this->namespaces, $this->expectedDefinitions);
+    $plugin_manager->setFallbackPluginId('apple');
+    $plugin_manager->setFactory($factory);
+    $plugin = $plugin_manager->createInstance('non_existing', array('key' => 'value'));
+    $this->assertSame($apple, $plugin);
+  }
+
 }
 
 if (!defined('DRUPAL_ROOT')) {
diff --git a/core/tests/Drupal/Tests/Core/Plugin/TestPluginManager.php b/core/tests/Drupal/Tests/Core/Plugin/TestPluginManager.php
index a7ea79d..4619640 100644
--- a/core/tests/Drupal/Tests/Core/Plugin/TestPluginManager.php
+++ b/core/tests/Drupal/Tests/Core/Plugin/TestPluginManager.php
@@ -8,6 +8,7 @@
 namespace Drupal\Tests\Core\Plugin;
 
 use Drupal\Component\Plugin\Discovery\StaticDiscovery;
+use Drupal\Component\Plugin\Factory\FactoryInterface;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Plugin\DefaultPluginManager;
 
@@ -28,6 +29,8 @@ class TestPluginManager extends DefaultPluginManager {
    *   (optional) The module handler to invoke the alter hook with.
    * @param string $alter_hook
    *   (optional) Name of the alter hook.
+   * @param string $fallback_plugin_id
+   *   (optional) The fallback plugin ID.
    */
   public function __construct(\Traversable $namespaces, array $definitions, ModuleHandlerInterface $module_handler = NULL, $alter_hook = NULL) {
     // Create the object that can be used to return definitions for all the
@@ -48,4 +51,14 @@ public function __construct(\Traversable $namespaces, array $definitions, Module
     }
   }
 
+  /**
+   * Sets the plugin factory.
+   *
+   * @param \Drupal\Component\Plugin\Factory\FactoryInterface $factory
+   *   (optional) The plugin factory.
+   */
+  public function setFactory(FactoryInterface $factory) {
+    $this->factory = $factory;
+  }
+
 }
