diff --git a/core/lib/Drupal/Component/Annotation/Plugin/Discovery/AnnotatedClassDiscovery.php b/core/lib/Drupal/Component/Annotation/Plugin/Discovery/AnnotatedClassDiscovery.php
index e564fd0..f76e28e 100644
--- a/core/lib/Drupal/Component/Annotation/Plugin/Discovery/AnnotatedClassDiscovery.php
+++ b/core/lib/Drupal/Component/Annotation/Plugin/Discovery/AnnotatedClassDiscovery.php
@@ -142,7 +142,7 @@ public function getDefinitions() {
 
               /** @var $annotation \Drupal\Component\Annotation\AnnotationInterface */
               if ($annotation = $reader->getClassAnnotation($parser->getReflectionClass(), $this->pluginDefinitionAnnotationName)) {
-                $this->prepareAnnotationDefinition($annotation, $class);
+                $this->prepareAnnotationDefinition($annotation, $class, $parser);
 
                 $id = $annotation->getId();
                 $content = $annotation->get();
@@ -173,8 +173,10 @@ public function getDefinitions() {
    *   The annotation derived from the plugin.
    * @param string $class
    *   The class used for the plugin.
+   * @param \Doctrine\Common\Reflection\StaticReflectionParser $parser
+   *   The static reflection parser.
    */
-  protected function prepareAnnotationDefinition(AnnotationInterface $annotation, $class) {
+  protected function prepareAnnotationDefinition(AnnotationInterface $annotation, $class, StaticReflectionParser $parser) {
     $annotation->setClass($class);
   }
 
diff --git a/core/lib/Drupal/Component/Plugin/Discovery/DerivativeDiscoveryDecorator.php b/core/lib/Drupal/Component/Plugin/Discovery/DerivativeDiscoveryDecorator.php
index 2028f40..a5d4245 100644
--- a/core/lib/Drupal/Component/Plugin/Discovery/DerivativeDiscoveryDecorator.php
+++ b/core/lib/Drupal/Component/Plugin/Discovery/DerivativeDiscoveryDecorator.php
@@ -3,6 +3,7 @@
 namespace Drupal\Component\Plugin\Discovery;
 
 use Drupal\Component\Plugin\Exception\InvalidDeriverException;
+use Drupal\Core\Plugin\Discovery\FilterDiscoveryInterface;
 
 /**
  * Base class providing the tools for a plugin discovery to be derivative aware.
@@ -30,6 +31,13 @@ class DerivativeDiscoveryDecorator implements DiscoveryInterface {
   protected $decorated;
 
   /**
+   * A list of filters to apply to the plugin definitions before deriving.
+   *
+   * @var \Drupal\Core\Plugin\Discovery\FilterDiscoveryInterface[]
+   */
+  protected $filters = [];
+
+  /**
    * Creates a new instance.
    *
    * @param \Drupal\Component\Plugin\Discovery\DiscoveryInterface $decorated
@@ -83,6 +91,10 @@ public function getDefinition($plugin_id, $exception_on_invalid = TRUE) {
    */
   public function getDefinitions() {
     $plugin_definitions = $this->decorated->getDefinitions();
+    /** @var \Drupal\Core\Plugin\Discovery\FilterDiscoveryInterface $filter */
+    foreach ($this->filters as $filter) {
+      $plugin_definitions = $filter->filter($plugin_definitions);
+    }
     return $this->getDerivatives($plugin_definitions);
   }
 
@@ -241,4 +253,11 @@ public function __call($method, $args) {
     return call_user_func_array(array($this->decorated, $method), $args);
   }
 
+  /**
+   * @param \Drupal\Core\Plugin\Discovery\FilterDiscoveryInterface $filter
+   */
+  public function addFilter(FilterDiscoveryInterface $filter) {
+    $this->filters[] = $filter;
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php b/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php
index 06365fa..93868b2 100644
--- a/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php
+++ b/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php
@@ -14,6 +14,7 @@
 use Drupal\Core\Cache\Cache;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery;
+use Drupal\Core\Plugin\Discovery\FilterDiscoveryByProvider;
 use Drupal\Core\Plugin\Factory\ContainerFactory;
 
 /**
@@ -277,19 +278,7 @@ protected function findDefinitions() {
       $this->processDefinition($definition, $plugin_id);
     }
     $this->alterDefinitions($definitions);
-    // 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'])) {
-        unset($definitions[$plugin_id]);
-      }
-    }
-    return $definitions;
+    return (new FilterDiscoveryByProvider($this->moduleHandler->getModuleList()))->filter($definitions);
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Plugin/Discovery/AnnotatedClassDiscovery.php b/core/lib/Drupal/Core/Plugin/Discovery/AnnotatedClassDiscovery.php
index 770308d..70282d1 100644
--- a/core/lib/Drupal/Core/Plugin/Discovery/AnnotatedClassDiscovery.php
+++ b/core/lib/Drupal/Core/Plugin/Discovery/AnnotatedClassDiscovery.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Core\Plugin\Discovery;
 
+use Doctrine\Common\Reflection\StaticReflectionParser;
 use Drupal\Component\Annotation\AnnotationInterface;
 use Drupal\Component\Annotation\Plugin\Discovery\AnnotatedClassDiscovery as ComponentAnnotatedClassDiscovery;
 use Drupal\Component\Utility\Unicode;
@@ -82,11 +83,11 @@ protected function getAnnotationReader() {
   /**
    * {@inheritdoc}
    */
-  protected function prepareAnnotationDefinition(AnnotationInterface $annotation, $class) {
-    parent::prepareAnnotationDefinition($annotation, $class);
+  protected function prepareAnnotationDefinition(AnnotationInterface $annotation, $class, StaticReflectionParser $parser) {
+    parent::prepareAnnotationDefinition($annotation, $class, $parser);
 
     if (!$annotation->getProvider()) {
-      $annotation->setProvider($this->getProviderFromNamespace($class));
+      $annotation->setProvider(static::getProviderFromNamespace($class));
     }
   }
 
@@ -96,10 +97,10 @@ protected function prepareAnnotationDefinition(AnnotationInterface $annotation,
    * @param string $namespace
    *   The namespace to extract the provider from.
    *
-   * @return string|null
+   * @return null|string
    *   The matching provider name, or NULL otherwise.
    */
-  protected function getProviderFromNamespace($namespace) {
+  static public function getProviderFromNamespace($namespace) {
     preg_match('|^Drupal\\\\(?<provider>[\w]+)\\\\|', $namespace, $matches);
 
     if (isset($matches['provider'])) {
diff --git a/core/lib/Drupal/Core/Plugin/Discovery/AnnotatedClassDiscoveryAutomatedProviders.php b/core/lib/Drupal/Core/Plugin/Discovery/AnnotatedClassDiscoveryAutomatedProviders.php
new file mode 100644
index 0000000..e750713
--- /dev/null
+++ b/core/lib/Drupal/Core/Plugin/Discovery/AnnotatedClassDiscoveryAutomatedProviders.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace Drupal\Core\Plugin\Discovery;
+
+
+use Doctrine\Common\Reflection\StaticReflectionParser;
+use Drupal\Component\Annotation\AnnotationInterface;
+
+class AnnotatedClassDiscoveryAutomatedProviders extends AnnotatedClassDiscovery {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function prepareAnnotationDefinition(AnnotationInterface $annotation, $class, StaticReflectionParser $parser) {
+    $provider_set = $annotation->getProvider();
+    parent::prepareAnnotationDefinition($annotation, $class, $parser);
+
+    if (!$provider_set) {
+      $namespaces[$annotation->getProvider()] = TRUE;
+      foreach ($parser->getUseStatements() as $class) {
+        if ($namespace = AnnotatedClassDiscovery::getProviderFromNamespace($class)) {
+          $namespaces[strtolower($namespace)] = TRUE;
+        }
+      }
+      $annotation->setProvider(array_keys($namespaces));
+    }
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Plugin/Discovery/FilterDiscoveryByProvider.php b/core/lib/Drupal/Core/Plugin/Discovery/FilterDiscoveryByProvider.php
new file mode 100644
index 0000000..b438cbf
--- /dev/null
+++ b/core/lib/Drupal/Core/Plugin/Discovery/FilterDiscoveryByProvider.php
@@ -0,0 +1,50 @@
+<?php
+
+namespace Drupal\Core\Plugin\Discovery;
+
+/**
+ * Remove plugin definitions with non-existing providers.
+ */
+class FilterDiscoveryByProvider implements FilterDiscoveryInterface {
+
+  /**
+   * @var array
+   */
+  protected $providers;
+
+  /**
+   * @param \Drupal\Core\Extension\Extension[] $module_list
+   *   An associative array whose keys are the names of the modules and whose
+   *   values are Extension objects.
+   */
+  public function __construct($module_list) {
+    $this->providers = array_keys($module_list + ['core' => TRUE, 'component' => TRUE]);
+  }
+
+  /**
+   * Remove plugin definitions with non-existing providers.
+   *
+   * @param array $definitions
+   *   An array of plugin definitions.
+   *
+   * @return array
+   *   An array of plugin definitions. If a definition is an array and it has
+   *   a provider key that provider or providers are guaranteed to exist.
+   */
+  public function filter(array $definitions) {
+    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)) || !isset($plugin_definition['provider'])) {
+        continue;
+      }
+      foreach ((array) $plugin_definition['provider'] as $provider) {
+        if (!isset($this->providers[$provider])) {
+          unset($definitions[$plugin_id]);
+        }
+      }
+    }
+    return $definitions;
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Plugin/Discovery/FilterDiscoveryInterface.php b/core/lib/Drupal/Core/Plugin/Discovery/FilterDiscoveryInterface.php
new file mode 100644
index 0000000..15b9661
--- /dev/null
+++ b/core/lib/Drupal/Core/Plugin/Discovery/FilterDiscoveryInterface.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace Drupal\Core\Plugin\Discovery;
+
+
+interface FilterDiscoveryInterface {
+
+  /**
+   * Remove public plugin definitions.
+   *
+   * @param array $definitions
+   *   An array of plugin definitions.
+   *
+   * @return array
+   *   A filtered array of plugin definitions.
+   */
+  public function filter(array $definitions);
+
+}
diff --git a/core/modules/migrate/migrate.services.yml b/core/modules/migrate/migrate.services.yml
index da43b38..254de2a 100644
--- a/core/modules/migrate/migrate.services.yml
+++ b/core/modules/migrate/migrate.services.yml
@@ -6,7 +6,7 @@ services:
     factory: cache_factory:get
     arguments: [migrate]
   plugin.manager.migrate.source:
-    class: Drupal\migrate\Plugin\MigratePluginManager
+    class: Drupal\migrate\Plugin\MigrateSourcePluginManager
     arguments: [source, '@container.namespaces', '@cache.discovery', '@module_handler', 'Drupal\migrate\Annotation\MigrateSource']
   plugin.manager.migrate.process:
     class: Drupal\migrate\Plugin\MigratePluginManager
diff --git a/core/modules/migrate/src/Plugin/InheritProviderDecorator.php b/core/modules/migrate/src/Plugin/InheritProviderDecorator.php
new file mode 100644
index 0000000..e907383
--- /dev/null
+++ b/core/modules/migrate/src/Plugin/InheritProviderDecorator.php
@@ -0,0 +1,52 @@
+<?php
+
+namespace Drupal\migrate\Plugin;
+
+use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
+use Drupal\Component\Plugin\Discovery\DiscoveryTrait;
+
+class InheritProviderDecorator implements DiscoveryInterface {
+
+  use DiscoveryTrait;
+
+  /**
+   * The Discovery object being decorated.
+   *
+   * @var \Drupal\Component\Plugin\Discovery\DiscoveryInterface
+   */
+  protected $decorated;
+
+  /**
+   * Constructs a InheritProviderDecorator object.
+   *
+   * @param \Drupal\Component\Plugin\Discovery\DiscoveryInterface $decorated
+   *   The object implementing DiscoveryInterface that is being decorated.
+   */
+  public function __construct(DiscoveryInterface $decorated) {
+    $this->decorated = $decorated;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getDefinitions() {
+    $source_plugin_manager = \Drupal::service('plugin.manager.migrate.source');
+    return array_map(function (array $definition) use ($source_plugin_manager) {
+      $definition += ['provider' => []];
+      $definition['provider'] = (array) $definition['provider'];
+      $source_plugin_definition = $source_plugin_manager->getDefinition($definition['source']['plugin']);
+      if (isset($source_plugin_definition['provider'])) {
+        $definition['provider'] = array_merge($definition['provider'], $source_plugin_definition['provider']);
+      }
+      return $definition;
+    }, $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/modules/migrate/src/Plugin/MigrateSourcePluginManager.php b/core/modules/migrate/src/Plugin/MigrateSourcePluginManager.php
new file mode 100644
index 0000000..8a688aa
--- /dev/null
+++ b/core/modules/migrate/src/Plugin/MigrateSourcePluginManager.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace Drupal\migrate\Plugin;
+
+use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscoveryAutomatedProviders;
+use Drupal\Core\Plugin\Discovery\ContainerDerivativeDiscoveryDecorator;
+
+class MigrateSourcePluginManager extends MigratePluginManager {
+
+  protected function getDiscovery() {
+    if (!$this->discovery) {
+      $discovery = new AnnotatedClassDiscoveryAutomatedProviders($this->subdir, $this->namespaces, $this->pluginDefinitionAnnotationName, $this->additionalAnnotationNamespaces);
+      $this->discovery = new ContainerDerivativeDiscoveryDecorator($discovery);
+    }
+    return $this->discovery;
+  }
+
+}
+
diff --git a/core/modules/migrate/src/Plugin/MigrationPluginManager.php b/core/modules/migrate/src/Plugin/MigrationPluginManager.php
index d082c11..12dcc4a 100644
--- a/core/modules/migrate/src/Plugin/MigrationPluginManager.php
+++ b/core/modules/migrate/src/Plugin/MigrationPluginManager.php
@@ -9,6 +9,8 @@
 use Drupal\Core\Language\LanguageManagerInterface;
 use Drupal\Core\Plugin\DefaultPluginManager;
 use Drupal\Core\Plugin\Discovery\ContainerDerivativeDiscoveryDecorator;
+use Drupal\Core\Plugin\Discovery\FilterDiscoveryByProvider;
+use Drupal\Core\Plugin\Discovery\ProviderAwareContainerDerivativeDiscoveryDecorator;
 use Drupal\Core\Plugin\Discovery\YamlDirectoryDiscovery;
 use Drupal\Core\Plugin\Factory\ContainerFactory;
 use Drupal\migrate\MigrateBuildDependencyInterface;
@@ -68,7 +70,9 @@ protected function getDiscovery() {
       }, $this->moduleHandler->getModuleDirectories());
 
       $yaml_discovery = new YamlDirectoryDiscovery($directories, 'migrate');
-      $this->discovery = new ContainerDerivativeDiscoveryDecorator($yaml_discovery);
+      $inherited_discovery = new InheritProviderDecorator($yaml_discovery)
+      $this->discovery = new ContainerDerivativeDiscoveryDecorator($inherited_discovery);
+      $this->discovery->addFilter(new FilterDiscoveryByProvider($this->moduleHandler->getModuleList()));
     }
     return $this->discovery;
   }
