diff --git a/core/lib/Drupal/Core/Block/BlockBase.php b/core/lib/Drupal/Core/Block/BlockBase.php
index bcc3954..02e5def 100644
--- a/core/lib/Drupal/Core/Block/BlockBase.php
+++ b/core/lib/Drupal/Core/Block/BlockBase.php
@@ -11,6 +11,7 @@
 use Drupal\Component\Utility\NestedArray;
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\Core\Plugin\PluginWithFormsInterface;
+use Drupal\Core\Plugin\PluginWithFormsTrait;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Component\Transliteration\TransliterationInterface;
 
@@ -26,6 +27,7 @@
 abstract class BlockBase extends ContextAwarePluginBase implements BlockPluginInterface, PluginWithFormsInterface {
 
   use ContextAwarePluginAssignmentTrait;
+  use PluginWithFormsTrait;
 
   /**
    * The transliteration service.
@@ -272,20 +274,4 @@ public function setTransliteration(TransliterationInterface $transliteration) {
     $this->transliteration = $transliteration;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public function getFormClass($operation) {
-    if ($this->hasFormClass($operation)) {
-      return $this->getPluginDefinition()['forms'][$operation];
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function hasFormClass($operation) {
-    return isset($this->getPluginDefinition()['forms'][$operation]);
-  }
-
 }
diff --git a/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php b/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php
index fa706a4..62decb2 100644
--- a/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php
+++ b/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php
@@ -247,12 +247,6 @@ public function processDefinition(&$definition, $plugin_id) {
     if (!empty($this->defaults) && is_array($this->defaults)) {
       $definition = NestedArray::mergeDeep($this->defaults, $definition);
     }
-
-    // If no default form is defined and this plugin implements
-    // \Drupal\Core\Plugin\PluginFormInterface, use that for the default form.
-    if (!isset($definition['forms']['configure']) && isset($definition['class']) && is_subclass_of($definition['class'], PluginFormInterface::class)) {
-      $definition['forms']['configure'] = $definition['class'];
-    }
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Plugin/PluginWithFormsTrait.php b/core/lib/Drupal/Core/Plugin/PluginWithFormsTrait.php
new file mode 100644
index 0000000..ec71720
--- /dev/null
+++ b/core/lib/Drupal/Core/Plugin/PluginWithFormsTrait.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace Drupal\Core\Plugin;
+
+/**
+ * Provides a trait with typical behavior for plugins which have forms.
+ */
+trait PluginWithFormsTrait {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormClass($operation) {
+    if (isset($this->getPluginDefinition()['forms'][$operation])) {
+      return $this->getPluginDefinition()['forms'][$operation];
+    }
+    elseif ($operation === 'configure' && $this instanceof PluginFormInterface) {
+      return static::class;
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function hasFormClass($operation) {
+    return !empty($this->getFormClass($operation));
+  }
+
+}
diff --git a/core/modules/system/system.install b/core/modules/system/system.install
index d705b5c..8ab78ff 100644
--- a/core/modules/system/system.install
+++ b/core/modules/system/system.install
@@ -1660,6 +1660,11 @@ function system_update_8014() {
  */
 
 /**
+ * @addtogroup updates-8.2.0
+ * @{
+ */
+
+/**
  * Fix configuration overrides to not override non existing keys.
  */
 function system_update_8200(&$sandbox) {
@@ -1681,3 +1686,14 @@ function system_update_8200(&$sandbox) {
   $sandbox['config_names'] = array_diff($sandbox['config_names'], $config_names_to_process);
   $sandbox['#finished'] = empty($sandbox['config_names']) ? 1 : ($sandbox['max'] - count($sandbox['config_names'])) / $sandbox['max'];
 }
+
+/**
+ * Clear caches due to behavior change in DefaultPluginManager.
+ */
+function system_update_8201() {
+  // Empty update to cause a cache rebuild.
+}
+
+/**
+ * @} End of "addtogroup updates-8.2.0".
+ */
diff --git a/core/modules/system/tests/modules/plugin_test/src/Plugin/plugin_test/fruit/ExtendingNonInstalledClass.php b/core/modules/system/tests/modules/plugin_test/src/Plugin/plugin_test/fruit/ExtendingNonInstalledClass.php
new file mode 100644
index 0000000..a42a474
--- /dev/null
+++ b/core/modules/system/tests/modules/plugin_test/src/Plugin/plugin_test/fruit/ExtendingNonInstalledClass.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace Drupal\plugin_test\Plugin\plugin_test\fruit;
+
+use Drupal\non_installed_module\Plugin\plugin_test\fruit\YummyFruit;
+
+/**
+ * @Plugin(
+ *   id = "extending_non_installed_class",
+ *   label = "A plugin whose class is extending from a non-installed module class",
+ *   color = "pink",
+ * )
+ */
+class ExtendingNonInstalledClass extends YummyFruit { }
diff --git a/core/tests/Drupal/KernelTests/Core/Plugin/Discovery/AnnotatedClassDiscoveryTest.php b/core/tests/Drupal/KernelTests/Core/Plugin/Discovery/AnnotatedClassDiscoveryTest.php
index bc68dc1..9a714c4 100644
--- a/core/tests/Drupal/KernelTests/Core/Plugin/Discovery/AnnotatedClassDiscoveryTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Plugin/Discovery/AnnotatedClassDiscoveryTest.php
@@ -64,6 +64,13 @@ protected function setUp() {
         'class' => 'Drupal\plugin_test_extended\Plugin\plugin_test\fruit\BigApple',
         'provider' => 'plugin_test_extended',
       ),
+      'extending_non_installed_class' => array(
+        'id' => 'extending_non_installed_class',
+        'label' => 'A plugin whose class is extending from a non-installed module class',
+        'color' => 'pink',
+        'class' => 'Drupal\plugin_test\Plugin\plugin_test\fruit\ExtendingNonInstalledClass',
+        'provider' => 'plugin_test',
+      ),
     );
 
     $base_directory = \Drupal::root() . '/core/modules/system/tests/modules/plugin_test/src';
diff --git a/core/tests/Drupal/KernelTests/Core/Plugin/Discovery/CustomDirectoryAnnotatedClassDiscoveryTest.php b/core/tests/Drupal/KernelTests/Core/Plugin/Discovery/CustomDirectoryAnnotatedClassDiscoveryTest.php
index 3d5d8c2..a9fbf79 100644
--- a/core/tests/Drupal/KernelTests/Core/Plugin/Discovery/CustomDirectoryAnnotatedClassDiscoveryTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Plugin/Discovery/CustomDirectoryAnnotatedClassDiscoveryTest.php
@@ -71,6 +71,13 @@ protected function setUp() {
         'class' => 'Drupal\plugin_test\Plugin\plugin_test\fruit\Orange',
         'provider' => 'plugin_test',
       ),
+      'extending_non_installed_class' => array(
+        'id' => 'extending_non_installed_class',
+        'label' => 'A plugin whose class is extending from a non-installed module class',
+        'color' => 'pink',
+        'class' => 'Drupal\plugin_test\Plugin\plugin_test\fruit\ExtendingNonInstalledClass',
+        'provider' => 'plugin_test',
+      ),
     );
 
     $base_directory = \Drupal::root() . '/core/modules/system/tests/modules/plugin_test/src';
diff --git a/core/tests/Drupal/Tests/Core/Plugin/DefaultPluginManagerTest.php b/core/tests/Drupal/Tests/Core/Plugin/DefaultPluginManagerTest.php
index feac004..ffdac5a 100644
--- a/core/tests/Drupal/Tests/Core/Plugin/DefaultPluginManagerTest.php
+++ b/core/tests/Drupal/Tests/Core/Plugin/DefaultPluginManagerTest.php
@@ -61,6 +61,25 @@ protected function setUp() {
   }
 
   /**
+   * Tests the plugin manager with a plugin that extends a non-installed class.
+   */
+  public function testDefaultPluginManagerWithPluginExtendingNonInstalledClass() {
+    $definitions = array();
+    $definitions['extending_non_installed_class'] = array(
+      'id' => 'extending_non_installed_class',
+      'label' => 'A plugin whose class is extending from a non-installed module class',
+      'color' => 'pink',
+      'class' => 'Drupal\plugin_test\Plugin\plugin_test\fruit\ExtendingNonInstalledClass',
+      'provider' => 'plugin_test',
+    );
+
+    $module_handler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface');
+    $plugin_manager = new TestPluginManager($this->namespaces, $definitions, $module_handler, 'test_alter_hook', '\Drupal\plugin_test\Plugin\plugin_test\fruit\FruitInterface');
+    $plugin_manager->getDefinition('plugin_test', FALSE);
+    $this->assertTrue(TRUE, 'No PHP fatal error occurred when retrieving the definitions of a module with plugins that depend on a non-installed module class should not cause a PHP fatal.');
+  }
+
+  /**
    * Tests the plugin manager with a disabled module.
    */
   public function testDefaultPluginManagerWithDisabledModule() {
@@ -383,7 +402,6 @@ public function providerTestProcessDefinition() {
     $data['no_form'][] = ['class' => TestPluginForm::class];
     $data['no_form'][] = [
       'class' => TestPluginForm::class,
-      'forms' => ['configure' => TestPluginForm::class],
       'foo' => ['bar' => ['baz']],
     ];
 
diff --git a/core/tests/Drupal/Tests/Core/Plugin/PluginWithFormsTraitTest.php b/core/tests/Drupal/Tests/Core/Plugin/PluginWithFormsTraitTest.php
new file mode 100644
index 0000000..92e79c5
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Plugin/PluginWithFormsTraitTest.php
@@ -0,0 +1,67 @@
+<?php
+
+namespace Drupal\Tests\Core\Plugin;
+
+use Drupal\Component\Plugin\PluginBase;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Plugin\PluginFormInterface;
+use Drupal\Core\Plugin\PluginWithFormsInterface;
+use Drupal\Core\Plugin\PluginWithFormsTrait;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * @coversDefaultClass \Drupal\Core\Plugin\PluginWithFormsTrait
+ * @group Plugin
+ */
+class PluginWithFormsTraitTest extends UnitTestCase {
+
+  /**
+   * @covers ::getFormClass
+   * @covers ::hasFormClass
+   * @dataProvider providerGetFormClass
+   */
+  public function testGetFormClass(PluginWithFormsInterface $block_plugin, $operation, $expected_class) {
+    $this->assertSame($expected_class, $block_plugin->getFormClass($operation));
+    $this->assertSame($expected_class !== NULL, $block_plugin->hasFormClass($operation));
+  }
+
+  /**
+   * @return array
+   */
+  public function providerGetFormClass() {
+    $block_plugin_without_forms = new TestClass([],  'block_plugin_without_forms', [
+      'provider' => 'block_test',
+    ]);
+    // A block plugin that has a form defined for the 'poke' operation.
+    $block_plugin_with_forms = new TestClass([], 'block_plugin_with_forms', [
+      'provider' => 'block_test',
+      'forms' => [
+        'poke' => static::class,
+      ],
+    ]);
+    return [
+      'block plugin without forms, "configure" operation' => [$block_plugin_without_forms, 'configure', TestClass::class],
+      'block plugin without forms, "tickle" operation'    => [$block_plugin_without_forms, 'tickle', NULL],
+      'block plugin withut forms, "poke" operation'       => [$block_plugin_without_forms, 'poke', NULL],
+      'block plugin with forms, "configure" operation' => [$block_plugin_with_forms, 'configure', TestClass::class],
+      'block plugin with forms, "tickle" operation'    => [$block_plugin_with_forms, 'tickle', NULL],
+      'block plugin with forms, "poke" operation'      => [$block_plugin_with_forms, 'poke', static::class],
+    ];
+  }
+
+}
+
+class TestClass extends PluginBase implements PluginWithFormsInterface, PluginFormInterface {
+  use PluginWithFormsTrait;
+
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
+    return [];
+  }
+
+  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
+  }
+
+  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
+  }
+
+}
