diff --git a/core/lib/Drupal/Component/Plugin/Definition/PluginDefinitionProviderInterface.php b/core/lib/Drupal/Component/Plugin/Definition/PluginDefinitionProviderInterface.php
new file mode 100644
index 0000000..744b792
--- /dev/null
+++ b/core/lib/Drupal/Component/Plugin/Definition/PluginDefinitionProviderInterface.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace Drupal\Component\Plugin\Definition;
+
+/**
+ * @todo Move to \Drupal\Component\Plugin\Definition\PluginDefinitionInterface.
+ */
+interface PluginDefinitionProviderInterface extends PluginDefinitionInterface {
+
+  /**
+   * Gets the plugin provider.
+   *
+   * The provider is the name of the module that provides the plugin, or "core',
+   * or "component".
+   *
+   * @return string
+   *   The provider.
+   */
+  public function getProvider();
+
+}
diff --git a/core/lib/Drupal/Core/Entity/EntityTypeInterface.php b/core/lib/Drupal/Core/Entity/EntityTypeInterface.php
index c6336c9..54332b3 100644
--- a/core/lib/Drupal/Core/Entity/EntityTypeInterface.php
+++ b/core/lib/Drupal/Core/Entity/EntityTypeInterface.php
@@ -2,7 +2,7 @@
 
 namespace Drupal\Core\Entity;
 
-use Drupal\Component\Plugin\Definition\PluginDefinitionInterface;
+use Drupal\Component\Plugin\Definition\PluginDefinitionProviderInterface;
 
 /**
  * Provides an interface for an entity type and its metadata.
@@ -12,7 +12,7 @@
  * implemented to alter existing data and fill-in defaults. Module-specific
  * properties should be documented in the hook implementations defining them.
  */
-interface EntityTypeInterface extends PluginDefinitionInterface {
+interface EntityTypeInterface extends PluginDefinitionProviderInterface {
 
   /**
    * The maximum length of ID, in characters.
@@ -56,14 +56,6 @@ public function set($property, $value);
   public function id();
 
   /**
-   * Gets the name of the provider of this entity type.
-   *
-   * @return string
-   *   The name of the provider of this entity type.
-   */
-  public function getProvider();
-
-  /**
    * Gets the name of the original entity type class.
    *
    * In case the class name was changed with setClass(), this will return
diff --git a/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php b/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php
index 62decb2..183bb19 100644
--- a/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php
+++ b/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Core\Plugin;
 
+use Drupal\Component\Plugin\Definition\PluginDefinitionProviderInterface;
 use Drupal\Component\Plugin\Discovery\CachedDiscoveryInterface;
 use Drupal\Core\Cache\CacheableDependencyInterface;
 use Drupal\Core\Cache\CacheBackendInterface;
@@ -285,12 +286,8 @@ protected function findDefinitions() {
     // If this plugin was provided by a module that does not exist, remove the
     // plugin definition.
     foreach ($definitions as $plugin_id => $plugin_definition) {
-      // If the plugin definition is an object, attempt to convert it to an
-      // array, if that is not possible, skip further processing.
-      if (is_object($plugin_definition) && !($plugin_definition = (array) $plugin_definition)) {
-        continue;
-      }
-      if (isset($plugin_definition['provider']) && !in_array($plugin_definition['provider'], array('core', 'component')) && !$this->providerExists($plugin_definition['provider'])) {
+      $provider = $this->extractProviderFromDefinition($plugin_definition);
+      if ($provider && !in_array($provider, array('core', 'component')) && !$this->providerExists($provider)) {
         unset($definitions[$plugin_id]);
       }
     }
@@ -298,6 +295,31 @@ protected function findDefinitions() {
   }
 
   /**
+   * Extracts the provider from a plugin definition.
+   *
+   * @param mixed $plugin_definition
+   *   The plugin definition. Usually either an array or an instance of
+   *   \Drupal\Component\Plugin\Definition\PluginDefinitionInterface
+   *
+   * @return string|null
+   *   The provider string, if it exists. NULL otherwise.
+   */
+  protected function extractProviderFromDefinition($plugin_definition) {
+    if ($plugin_definition instanceof PluginDefinitionProviderInterface) {
+      return $plugin_definition->getProvider();
+    }
+
+    // Attempt to convert the plugin definition to an array.
+    if (is_object($plugin_definition)) {
+      $plugin_definition = (array) $plugin_definition;
+    }
+
+    if (isset($plugin_definition['provider'])) {
+      return $plugin_definition['provider'];
+    }
+  }
+
+  /**
    * Invokes the hook to alter the definitions if the alter hook is set.
    *
    * @param $definitions
diff --git a/core/tests/Drupal/Tests/Core/Plugin/DefaultPluginManagerTest.php b/core/tests/Drupal/Tests/Core/Plugin/DefaultPluginManagerTest.php
index ffdac5a..d055ba4 100644
--- a/core/tests/Drupal/Tests/Core/Plugin/DefaultPluginManagerTest.php
+++ b/core/tests/Drupal/Tests/Core/Plugin/DefaultPluginManagerTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Tests\Core\Plugin;
 
+use Drupal\Component\Plugin\Definition\PluginDefinitionProviderInterface;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Plugin\PluginFormInterface;
@@ -360,6 +361,32 @@ public function testGetCacheMaxAge() {
   }
 
   /**
+   * @covers ::findDefinitions
+   * @covers ::extractProviderFromDefinition
+   */
+  public function testProviderExists() {
+    $definitions = [];
+    $definitions['array_based_found'] = ['provider' => 'module_found'];
+    $definitions['array_based_missing'] = ['provider' => 'module_missing'];
+    $definitions['stdclass_based_found'] = (object) ['provider' => 'module_found'];
+    $definitions['stdclass_based_missing'] = (object) ['provider' => 'module_missing'];
+    $definitions['classed_object_found'] = new ObjectDefinition(['provider' => 'module_found']);
+    $definitions['classed_object_missing'] = new ObjectDefinition(['provider' => 'module_missing']);
+
+    $expected = [];
+    $expected['array_based_found'] = $definitions['array_based_found'];
+    $expected['stdclass_based_found'] = $definitions['stdclass_based_found'];
+    $expected['classed_object_found'] = $definitions['classed_object_found'];
+
+    $module_handler = $this->prophesize(ModuleHandlerInterface::class);
+    $module_handler->moduleExists('module_found')->willReturn(TRUE)->shouldBeCalled();
+    $module_handler->moduleExists('module_missing')->willReturn(FALSE)->shouldBeCalled();
+    $plugin_manager = new TestPluginManager($this->namespaces, $definitions, $module_handler->reveal());
+    $result = $plugin_manager->getDefinitions();
+    $this->assertEquals($expected, $result);
+  }
+
+  /**
    * @covers ::processDefinition
    * @dataProvider providerTestProcessDefinition
    */
@@ -453,3 +480,49 @@ public function submitConfigurationForm(array &$form, FormStateInterface $form_s
   }
 
 }
+class ObjectDefinition implements PluginDefinitionProviderInterface {
+
+  /**
+   * @var string
+   */
+  protected $class;
+
+  /**
+   * @var string
+   */
+  protected $provider;
+
+  /**
+   * ObjectDefinition constructor.
+   *
+   * @param array $definition
+   */
+  public function __construct(array $definition) {
+    foreach ($definition as $property => $value) {
+      $this->{$property} = $value;
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setClass($class) {
+    $this->class = $class;
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getClass() {
+    return $this->class;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getProvider() {
+    return $this->provider;
+  }
+
+}
