diff --git a/core/includes/entity.inc b/core/includes/entity.inc
index 75c3386..3217e9f 100644
--- a/core/includes/entity.inc
+++ b/core/includes/entity.inc
@@ -43,17 +43,12 @@ function entity_get_info($entity_type = NULL) {
     else {
       $entity_info = module_invoke_all('entity_info');
       // Merge in default values.
+      $manager = drupal_container()->get('plugin.manager.entity');
       foreach ($entity_info as $name => $data) {
+        if ($definition = $manager->getDefinition($name)) {
+          $entity_info[$name] += $definition;
+        }
         $entity_info[$name] += array(
-          'fieldable' => FALSE,
-          'entity class' => 'Drupal\Core\Entity\Entity',
-          'controller class' => 'Drupal\Core\Entity\DatabaseStorageController',
-          'list controller class' => 'Drupal\Core\Entity\EntityListController',
-          'form controller class' => array(
-            'default' => 'Drupal\Core\Entity\EntityFormController',
-          ),
-          'static cache' => TRUE,
-          'field cache' => TRUE,
           'bundles' => array(),
           'view modes' => array(),
           'entity keys' => array(),
diff --git a/core/lib/Drupal/Core/CoreBundle.php b/core/lib/Drupal/Core/CoreBundle.php
index f1e43d6..2ad563b 100644
--- a/core/lib/Drupal/Core/CoreBundle.php
+++ b/core/lib/Drupal/Core/CoreBundle.php
@@ -66,6 +66,8 @@ public function build(ContainerBuilder $container) {
     $container->register('router.builder', 'Drupal\Core\Routing\RouteBuilder')
       ->addArgument(new Reference('router.dumper'));
 
+    $container->register('plugin.manager.entity', 'Drupal\Core\Plugin\Type\EntityManager');
+
     // @todo Replace below lines with the commented out block below it when it's
     //   performant to do so: http://drupal.org/node/1706064.
     $dispatcher = $container->get('dispatcher');
diff --git a/core/lib/Drupal/Core/Plugin/Type/EntityManager.php b/core/lib/Drupal/Core/Plugin/Type/EntityManager.php
new file mode 100644
index 0000000..bce8afe
--- /dev/null
+++ b/core/lib/Drupal/Core/Plugin/Type/EntityManager.php
@@ -0,0 +1,51 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\Core\Plugin\Type\EntityManager.
+ */
+
+namespace Drupal\Core\Plugin\Type;
+
+use Drupal\Component\Plugin\PluginManagerBase;
+use Drupal\Component\Plugin\Discovery\DerivativeDiscoveryDecorator;
+use Drupal\Component\Plugin\Factory\DefaultFactory;
+use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery;
+
+class EntityManager extends PluginManagerBase {
+
+  public function __construct() {
+    $this->discovery = new DerivativeDiscoveryDecorator(new AnnotatedClassDiscovery('Core', 'Entity'));
+    $this->factory = new DefaultFactory($this);
+
+    $this->defaults = array(
+      'fieldable' => FALSE,
+      'entity class' => 'Drupal\Core\Entity\Entity',
+      'controller class' => 'Drupal\Core\Entity\DatabaseStorageController',
+      'list controller class' => 'Drupal\Core\Entity\EntityListController',
+      'form controller class' => array(
+        'default' => 'Drupal\Core\Entity\EntityFormController',
+      ),
+      'static cache' => TRUE,
+      'field cache' => TRUE,
+    );
+  }
+
+  /**
+   * Overrides Drupal\Component\Plugin\PluginManagerBase::processDefinition().
+   */
+  protected function processDefinition(&$definition, $plugin_id) {
+    parent::processDefinition($definition, $plugin_id);
+
+    foreach ($definition as $key => $value) {
+      if (strpos($key, '_') !== FALSE) {
+        $new_key = str_replace('_', ' ', $key);
+        $definition[$new_key] = $value;
+      }
+    }
+    if (isset($definition['class'])) {
+      $definition['entity class'] = $definition['class'];
+    }
+  }
+
+}
diff --git a/core/modules/book/book.admin.inc b/core/modules/book/book.admin.inc
index d4d6f0b..4a605d2 100644
--- a/core/modules/book/book.admin.inc
+++ b/core/modules/book/book.admin.inc
@@ -5,7 +5,7 @@
  * Admin page callbacks for the book module.
  */
 
-use Drupal\node\Node;
+use Drupal\node\Plugin\Core\Entity\Node;
 
 /**
  * Page callback: Returns an administrative overview of all books.
diff --git a/core/modules/book/book.module b/core/modules/book/book.module
index fd4fac9..6587cc3 100644
--- a/core/modules/book/book.module
+++ b/core/modules/book/book.module
@@ -5,7 +5,7 @@
  * Allows users to create and organize related content in an outline.
  */
 
-use Drupal\node\Node;
+use Drupal\node\Plugin\Core\Entity\Node;
 use Drupal\Core\Template\Attribute;
 
 /**
diff --git a/core/modules/book/book.pages.inc b/core/modules/book/book.pages.inc
index 90b2192..ae79318 100644
--- a/core/modules/book/book.pages.inc
+++ b/core/modules/book/book.pages.inc
@@ -5,7 +5,7 @@
  * User page callbacks for the book module.
  */
 
-use Drupal\node\Node;
+use Drupal\node\Plugin\Core\Entity\Node;
 use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
 
diff --git a/core/modules/book/lib/Drupal/book/Tests/BookTest.php b/core/modules/book/lib/Drupal/book/Tests/BookTest.php
index a1a88c4..5f50fe8 100644
--- a/core/modules/book/lib/Drupal/book/Tests/BookTest.php
+++ b/core/modules/book/lib/Drupal/book/Tests/BookTest.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\book\Tests;
 
-use Drupal\node\Node;
+use Drupal\node\Plugin\Core\Entity\Node;
 use Drupal\simpletest\WebTestBase;
 
 class BookTest extends WebTestBase {
diff --git a/core/modules/comment/comment.admin.inc b/core/modules/comment/comment.admin.inc
index dcbd1bc..26e9c8b 100644
--- a/core/modules/comment/comment.admin.inc
+++ b/core/modules/comment/comment.admin.inc
@@ -5,7 +5,7 @@
  * Admin page callbacks for the Comment module.
  */
 
-use Drupal\comment\Comment;
+use Drupal\comment\Plugin\Core\Entity\Comment;
 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
 
 /**
diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module
index 27ff7c3..f14b620 100644
--- a/core/modules/comment/comment.module
+++ b/core/modules/comment/comment.module
@@ -9,8 +9,8 @@
  * book page, etc.
  */
 
-use Drupal\node\Node;
-use Drupal\file\File;
+use Drupal\node\Plugin\Core\Entity\Node;
+use Drupal\file\Plugin\Core\Entity\File;
 use Drupal\Core\Entity\EntityInterface;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
@@ -76,7 +76,7 @@
  */
 const COMMENT_NODE_OPEN = 2;
 
-use Drupal\comment\Comment;
+use Drupal\comment\Plugin\Core\Entity\Comment;
 
 /**
  * Implements hook_help().
@@ -103,21 +103,6 @@ function comment_help($path, $arg) {
 function comment_entity_info() {
   $return = array(
     'comment' => array(
-      'label' => t('Comment'),
-      'base table' => 'comment',
-      'uri callback' => 'comment_uri',
-      'fieldable' => TRUE,
-      'controller class' => 'Drupal\comment\CommentStorageController',
-      'form controller class' => array(
-        'default' => 'Drupal\comment\CommentFormController',
-      ),
-      'entity class' => 'Drupal\comment\Comment',
-      'entity keys' => array(
-        'id' => 'cid',
-        'bundle' => 'node_type',
-        'label' => 'subject',
-        'uuid' => 'uuid',
-      ),
       'bundles' => array(),
       'view modes' => array(
         'full' => array(
@@ -125,7 +110,6 @@ function comment_entity_info() {
           'custom settings' => FALSE,
         ),
       ),
-      'static cache' => FALSE,
     ),
   );
 
diff --git a/core/modules/comment/comment.pages.inc b/core/modules/comment/comment.pages.inc
index ed91d23..5b76f20 100644
--- a/core/modules/comment/comment.pages.inc
+++ b/core/modules/comment/comment.pages.inc
@@ -5,7 +5,7 @@
  * User page callbacks for the Comment module.
  */
 
-use Drupal\node\Node;
+use Drupal\node\Plugin\Core\Entity\Node;
 use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
 
diff --git a/core/modules/comment/lib/Drupal/comment/Comment.php b/core/modules/comment/lib/Drupal/comment/Plugin/Core/Entity/Comment.php
similarity index 69%
rename from core/modules/comment/lib/Drupal/comment/Comment.php
rename to core/modules/comment/lib/Drupal/comment/Plugin/Core/Entity/Comment.php
index 9b507e7..2308881 100644
--- a/core/modules/comment/lib/Drupal/comment/Comment.php
+++ b/core/modules/comment/lib/Drupal/comment/Plugin/Core/Entity/Comment.php
@@ -2,16 +2,37 @@
 
 /**
  * @file
- * Definition of Drupal\comment\Comment.
+ * Definition of Drupal\comment\Plugin\Core\Entity\Comment.
  */
 
-namespace Drupal\comment;
+namespace Drupal\comment\Plugin\Core\Entity;
 
 use Drupal\Core\Entity\ContentEntityInterface;
 use Drupal\Core\Entity\Entity;
+use Drupal\Core\Annotation\Plugin;
+use Drupal\Core\Annotation\Translation;
 
 /**
  * Defines the comment entity class.
+ *
+ * @Plugin(
+ *   id = "comment",
+ *   label = @Translation("Comment"),
+ *   controller_class = "Drupal\comment\CommentStorageController",
+ *   form_controller_class = {
+ *     "default" = "Drupal\comment\CommentFormController"
+ *   },
+ *   base_table = "comment",
+ *   uri_callback = "comment_uri",
+ *   fieldable = TRUE,
+ *   static_cache = FALSE,
+ *   entity_keys = {
+ *     "id" = "cid",
+ *     "bundle" = "node_type",
+ *     "label" = "subject",
+ *     "uuid" = "uuid"
+ *   }
+ * )
  */
 class Comment extends Entity implements ContentEntityInterface {
 
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentTestBase.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentTestBase.php
index 60216ab..6cac70c 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/CommentTestBase.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentTestBase.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\comment\Tests;
 
-use Drupal\comment\Comment;
+use Drupal\comment\Plugin\Core\Entity\Comment;
 use Drupal\simpletest\WebTestBase;
 
 abstract class CommentTestBase extends WebTestBase {
diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigEntityListTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigEntityListTest.php
index cd48f71..80698c1 100644
--- a/core/modules/config/lib/Drupal/config/Tests/ConfigEntityListTest.php
+++ b/core/modules/config/lib/Drupal/config/Tests/ConfigEntityListTest.php
@@ -8,7 +8,7 @@
 namespace Drupal\config\Tests;
 
 use Drupal\simpletest\WebTestBase;
-use Drupal\config_test\ConfigTest;
+use Drupal\config_test\Plugin\Core\Entity\ConfigTest;
 use Drupal\Core\Entity\EntityStorageControllerInterface;
 
 /**
diff --git a/core/modules/config/tests/config_test/config_test.module b/core/modules/config/tests/config_test/config_test.module
index 44df4da..9a29a19 100644
--- a/core/modules/config/tests/config_test/config_test.module
+++ b/core/modules/config/tests/config_test/config_test.module
@@ -5,7 +5,7 @@
  * Provides Config module hook implementations for testing purposes.
  */
 
-use Drupal\config_test\ConfigTest;
+use Drupal\config_test\Plugin\Core\Entity\ConfigTest;
 
 require_once dirname(__FILE__) . '/config_test.hooks.inc';
 
@@ -78,26 +78,14 @@ function config_test_config_import_delete($name, $new_config, $old_config) {
  * Implements hook_entity_info().
  */
 function config_test_entity_info() {
-  $types['config_test'] = array(
-    'label' => 'Test configuration',
-    'controller class' => 'Drupal\Core\Config\Entity\ConfigStorageController',
-    'entity class' => 'Drupal\config_test\ConfigTest',
-    'list controller class' => 'Drupal\Core\Config\Entity\ConfigEntityListController',
-    'uri callback' => 'config_test_uri',
-    'config prefix' => 'config_test.dynamic',
-    'entity keys' => array(
-      'id' => 'id',
-      'label' => 'label',
-      'uuid' => 'uuid',
-    ),
-  );
+  $types['config_test'] = array();
   return $types;
 }
 
 /**
  * Entity URI callback.
  *
- * @param Drupal\config_test\ConfigTest $config_test
+ * @param Drupal\config_test\Plugin\Core\Entity\ConfigTest $config_test
  *   A ConfigTest entity.
  */
 function config_test_uri(ConfigTest $config_test) {
@@ -156,7 +144,7 @@ function config_test_load($id) {
 /**
  * Saves a ConfigTest object.
  *
- * @param Drupal\config_test\ConfigTest $config_test
+ * @param Drupal\config_test\Plugin\Core\Entity\ConfigTest $config_test
  *   The ConfigTest object to save.
  */
 function config_test_save(ConfigTest $config_test) {
@@ -184,7 +172,7 @@ function config_test_list_page() {
 /**
  * Form constructor to add or edit a ConfigTest object.
  *
- * @param Drupal\config_test\ConfigTest $config_test
+ * @param Drupal\config_test\Plugin\Core\Entity\ConfigTest $config_test
  *   (optional) An existing ConfigTest object to edit. If omitted, the form
  *   creates a new ConfigTest.
  */
@@ -260,7 +248,7 @@ function config_test_form_submit($form, &$form_state) {
 /**
  * Form constructor to delete a ConfigTest object.
  *
- * @param Drupal\config_test\ConfigTest $config_test
+ * @param Drupal\config_test\Plugin\Core\Entity\ConfigTest $config_test
  *   The ConfigTest object to delete.
  */
 function config_test_delete_form($form, &$form_state, ConfigTest $config_test) {
diff --git a/core/modules/config/tests/config_test/lib/Drupal/config_test/ConfigTest.php b/core/modules/config/tests/config_test/lib/Drupal/config_test/ConfigTest.php
deleted file mode 100644
index e1df5c4..0000000
--- a/core/modules/config/tests/config_test/lib/Drupal/config_test/ConfigTest.php
+++ /dev/null
@@ -1,45 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\config_test\ConfigTest.
- */
-
-namespace Drupal\config_test;
-
-use Drupal\Core\Config\Entity\ConfigEntityBase;
-
-/**
- * Defines the ConfigTest configuration entity.
- */
-class ConfigTest extends ConfigEntityBase {
-
-  /**
-   * The machine name for the configuration entity.
-   *
-   * @var string
-   */
-  public $id;
-
-  /**
-   * The UUID for the configuration entity.
-   *
-   * @var string
-   */
-  public $uuid;
-
-  /**
-   * The human-readable name of the configuration entity.
-   *
-   * @var string
-   */
-  public $label;
-
-  /**
-   * The image style to use.
-   *
-   * @var string
-   */
-  public $style;
-
-}
diff --git a/core/modules/config/tests/config_test/lib/Drupal/config_test/Plugin/Core/Entity/ConfigTest.php b/core/modules/config/tests/config_test/lib/Drupal/config_test/Plugin/Core/Entity/ConfigTest.php
new file mode 100644
index 0000000..bacd7c1
--- /dev/null
+++ b/core/modules/config/tests/config_test/lib/Drupal/config_test/Plugin/Core/Entity/ConfigTest.php
@@ -0,0 +1,61 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\config_test\Plugin\Core\Entity\ConfigTest.
+ */
+
+namespace Drupal\config_test\Plugin\Core\Entity;
+
+use Drupal\Core\Config\Entity\ConfigEntityBase;
+use Drupal\Core\Annotation\Plugin;
+use Drupal\Core\Annotation\Translation;
+
+/**
+ * Defines the ConfigTest configuration entity.
+ *
+ * @Plugin(
+ *   id = "config_test",
+ *   label = @Translation("Test configuration"),
+ *   controller_class = "Drupal\Core\Config\Entity\ConfigStorageController",
+ *   list_controller_class = "Drupal\Core\Config\Entity\ConfigEntityListController",
+ *   uri_callback = "config_test_uri",
+ *   config_prefix = "config_test.dynamic",
+ *   entity_keys = {
+ *     "id" = "id",
+ *     "label" = "label",
+ *     "uuid" = "uuid"
+ *   }
+ * )
+ */
+class ConfigTest extends ConfigEntityBase {
+
+  /**
+   * The machine name for the configuration entity.
+   *
+   * @var string
+   */
+  public $id;
+
+  /**
+   * The UUID for the configuration entity.
+   *
+   * @var string
+   */
+  public $uuid;
+
+  /**
+   * The human-readable name of the configuration entity.
+   *
+   * @var string
+   */
+  public $label;
+
+  /**
+   * The image style to use.
+   *
+   * @var string
+   */
+  public $style;
+
+}
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php
index 96f59a2..a1c854f 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\field_ui\Tests;
 
-use Drupal\node\Node;
+use Drupal\node\Plugin\Core\Entity\Node;
 
 /**
  * Tests the functionality of the 'Manage display' screens.
diff --git a/core/modules/file/file.module b/core/modules/file/file.module
index 0f6cb64..c40543b 100644
--- a/core/modules/file/file.module
+++ b/core/modules/file/file.module
@@ -6,7 +6,7 @@
  */
 
 use Drupal\Core\Entity\EntityFieldQuery;
-use Drupal\file\File;
+use Drupal\file\Plugin\Core\Entity\File;
 use Drupal\Core\Template\Attribute;
 use Symfony\Component\HttpFoundation\JsonResponse;
 
@@ -91,16 +91,6 @@ function file_element_info() {
 function file_entity_info() {
   return array(
     'file' => array(
-      'label' => t('File'),
-      'base table' => 'file_managed',
-      'controller class' => 'Drupal\file\FileStorageController',
-      'entity class' => 'Drupal\file\File',
-      'entity keys' => array(
-        'id' => 'fid',
-        'label' => 'filename',
-        'uuid' => 'uuid',
-      ),
-      'static cache' => FALSE,
     ),
   );
 }
diff --git a/core/modules/file/lib/Drupal/file/File.php b/core/modules/file/lib/Drupal/file/Plugin/Core/Entity/File.php
similarity index 76%
rename from core/modules/file/lib/Drupal/file/File.php
rename to core/modules/file/lib/Drupal/file/Plugin/Core/Entity/File.php
index 9b965e3..ea75d44 100644
--- a/core/modules/file/lib/Drupal/file/File.php
+++ b/core/modules/file/lib/Drupal/file/Plugin/Core/Entity/File.php
@@ -2,15 +2,30 @@
 
 /**
  * @file
- * Definition of Drupal\file\File.
+ * Definition of Drupal\file\Plugin\Core\Entity\File.
  */
 
-namespace Drupal\file;
+namespace Drupal\file\Plugin\Core\Entity;
 
 use Drupal\Core\Entity\Entity;
+use Drupal\Core\Annotation\Plugin;
+use Drupal\Core\Annotation\Translation;
 
 /**
  * Defines the file entity class.
+ *
+ * @Plugin(
+ *   id = "file",
+ *   label = @Translation("File"),
+ *   controller_class = "Drupal\file\FileStorageController",
+ *   base_table = "file_managed",
+ *   static_cache = FALSE,
+ *   entity_keys = {
+ *     "id" = "fid",
+ *     "label" = "filename",
+ *     "uuid" = "uuid"
+ *   }
+ * )
  */
 class File extends Entity {
 
diff --git a/core/modules/file/tests/file_module_test.module b/core/modules/file/tests/file_module_test.module
index eae577e..b962e2a 100644
--- a/core/modules/file/tests/file_module_test.module
+++ b/core/modules/file/tests/file_module_test.module
@@ -6,7 +6,7 @@
  */
 
 use Drupal\Core\Entity\EntityInterface;
-use Drupal\file\File;
+use Drupal\file\Plugin\Core\Entity\File;
 
 /**
  * Implements hook_menu().
diff --git a/core/modules/file/tests/file_test/file_test.module b/core/modules/file/tests/file_test/file_test.module
index 46b8604..d4a4359 100644
--- a/core/modules/file/tests/file_test/file_test.module
+++ b/core/modules/file/tests/file_test/file_test.module
@@ -8,7 +8,7 @@
  * calling file_test_get_calls() or file_test_set_return().
  */
 
-use Drupal\file\File;
+use Drupal\file\Plugin\Core\Entity\File;
 
 const FILE_URL_TEST_CDN_1 = 'http://cdn1.example.com';
 const FILE_URL_TEST_CDN_2 = 'http://cdn2.example.com';
diff --git a/core/modules/forum/forum.module b/core/modules/forum/forum.module
index f365491..534c8b5 100644
--- a/core/modules/forum/forum.module
+++ b/core/modules/forum/forum.module
@@ -5,8 +5,8 @@
  * Provides discussion forums.
  */
 
-use Drupal\node\Node;
-use Drupal\taxonomy\Term;
+use Drupal\node\Plugin\Core\Entity\Node;
+use Drupal\taxonomy\Plugin\Core\Entity\Term;
 
 /**
  * Implements hook_help().
diff --git a/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php b/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php
index a253e2b..af25833 100644
--- a/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php
+++ b/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\forum\Tests;
 
-use Drupal\node\Node;
+use Drupal\node\Plugin\Core\Entity\Node;
 use Drupal\simpletest\WebTestBase;
 
 /**
diff --git a/core/modules/image/image.module b/core/modules/image/image.module
index 01d2b3b..082b2a9 100644
--- a/core/modules/image/image.module
+++ b/core/modules/image/image.module
@@ -9,7 +9,7 @@
 use Symfony\Component\HttpFoundation\StreamedResponse;
 use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
 use Drupal\Component\Uuid\Uuid;
-use Drupal\file\File;
+use Drupal\file\Plugin\Core\Entity\File;
 
 /**
  * Image style constant for user presets in the database.
diff --git a/core/modules/menu/menu.module b/core/modules/menu/menu.module
index cee4ba5..81fb51f 100644
--- a/core/modules/menu/menu.module
+++ b/core/modules/menu/menu.module
@@ -11,7 +11,7 @@
  * URLs to be added to the main site navigation menu.
  */
 
-use Drupal\node\Node;
+use Drupal\node\Plugin\Core\Entity\Node;
 
 use Symfony\Component\HttpFoundation\JsonResponse;
 
diff --git a/core/modules/node/lib/Drupal/node/Node.php b/core/modules/node/lib/Drupal/node/Plugin/Core/Entity/Node.php
similarity index 83%
rename from core/modules/node/lib/Drupal/node/Node.php
rename to core/modules/node/lib/Drupal/node/Plugin/Core/Entity/Node.php
index 45d93f0..c8bc3ac 100644
--- a/core/modules/node/lib/Drupal/node/Node.php
+++ b/core/modules/node/lib/Drupal/node/Plugin/Core/Entity/Node.php
@@ -2,16 +2,38 @@
 
 /**
  * @file
- * Definition of Drupal\node\Node.
+ * Definition of Drupal\node\Plugin\Core\Entity\Node.
  */
 
-namespace Drupal\node;
+namespace Drupal\node\Plugin\Core\Entity;
 
 use Drupal\Core\Entity\ContentEntityInterface;
 use Drupal\Core\Entity\Entity;
+use Drupal\Core\Annotation\Plugin;
+use Drupal\Core\Annotation\Translation;
 
 /**
  * Defines the node entity class.
+ *
+ * @Plugin(
+ *   id = "node",
+ *   label = @Translation("Node"),
+ *   controller_class = "Drupal\node\NodeStorageController",
+ *   form_controller_class = {
+ *     "default" = "Drupal\node\NodeFormController"
+ *   },
+ *   base_table = "node",
+ *   revision_table = "node_revision",
+ *   uri_callback = "node_uri",
+ *   fieldable = TRUE,
+ *   entity_keys = {
+ *     "id" = "nid",
+ *     "revision" = "vid",
+ *     "bundle" = "type",
+ *     "label" = "title",
+ *     "uuid" = "uuid"
+ *   }
+ * )
  */
 class Node extends Entity implements ContentEntityInterface {
 
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index 2dd1b57..582c5ba 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -15,8 +15,8 @@
 use Drupal\Core\Database\Query\SelectExtender;
 use Drupal\Core\Database\Query\SelectInterface;
 use Drupal\Core\Template\Attribute;
-use Drupal\node\Node;
-use Drupal\file\File;
+use Drupal\node\Plugin\Core\Entity\Node;
+use Drupal\file\Plugin\Core\Entity\File;
 use Drupal\Core\Entity\EntityInterface;
 
 /**
@@ -196,23 +196,6 @@ function node_cron() {
 function node_entity_info() {
   $return = array(
     'node' => array(
-      'label' => t('Node'),
-      'entity class' => 'Drupal\node\Node',
-      'controller class' => 'Drupal\node\NodeStorageController',
-      'form controller class' => array(
-        'default' => 'Drupal\node\NodeFormController',
-      ),
-      'base table' => 'node',
-      'revision table' => 'node_revision',
-      'uri callback' => 'node_uri',
-      'fieldable' => TRUE,
-      'entity keys' => array(
-        'id' => 'nid',
-        'revision' => 'vid',
-        'bundle' => 'type',
-        'label' => 'title',
-        'uuid' => 'uuid',
-      ),
       'bundle keys' => array(
         'bundle' => 'type',
       ),
diff --git a/core/modules/node/node.pages.inc b/core/modules/node/node.pages.inc
index 570ae88..8b94f17 100644
--- a/core/modules/node/node.pages.inc
+++ b/core/modules/node/node.pages.inc
@@ -9,7 +9,7 @@
  * @see node_menu()
  */
 
-use Drupal\node\Node;
+use Drupal\node\Plugin\Core\Entity\Node;
 
 /**
  * Page callback: Presents the node editing form.
diff --git a/core/modules/node/tests/modules/node_access_test/node_access_test.module b/core/modules/node/tests/modules/node_access_test/node_access_test.module
index a503217..bcd5a71 100644
--- a/core/modules/node/tests/modules/node_access_test/node_access_test.module
+++ b/core/modules/node/tests/modules/node_access_test/node_access_test.module
@@ -9,7 +9,7 @@
 
 use Drupal\Core\Entity\EntityFieldQuery;
 
-use Drupal\node\Node;
+use Drupal\node\Plugin\Core\Entity\Node;
 
 /**
  * Implements hook_node_grants().
diff --git a/core/modules/node/tests/modules/node_test/node_test.module b/core/modules/node/tests/modules/node_test/node_test.module
index 1686ff0..d3aa004 100644
--- a/core/modules/node/tests/modules/node_test/node_test.module
+++ b/core/modules/node/tests/modules/node_test/node_test.module
@@ -6,7 +6,7 @@
  * the Node module.
  */
 
-use Drupal\node\Node;
+use Drupal\node\Plugin\Core\Entity\Node;
 
 /**
  * Implements hook_node_load().
diff --git a/core/modules/node/tests/modules/node_test_exception/node_test_exception.module b/core/modules/node/tests/modules/node_test_exception/node_test_exception.module
index 570236b..c5d1129 100644
--- a/core/modules/node/tests/modules/node_test_exception/node_test_exception.module
+++ b/core/modules/node/tests/modules/node_test_exception/node_test_exception.module
@@ -6,7 +6,7 @@
  * the Node module.
  */
 
-use Drupal\node\Node;
+use Drupal\node\Plugin\Core\Entity\Node;
 
 /**
  * Implements hook_node_insert().
diff --git a/core/modules/path/path.module b/core/modules/path/path.module
index 6a69c13..942fbb6 100644
--- a/core/modules/path/path.module
+++ b/core/modules/path/path.module
@@ -5,9 +5,9 @@
  * Enables users to rename URLs.
  */
 
-use Drupal\node\Node;
+use Drupal\node\Plugin\Core\Entity\Node;
 
-use Drupal\taxonomy\Term;
+use Drupal\taxonomy\Plugin\Core\Entity\Term;
 
 /**
  * Implements hook_help().
diff --git a/core/modules/poll/poll.module b/core/modules/poll/poll.module
index c85f121..d3f8d3a 100644
--- a/core/modules/poll/poll.module
+++ b/core/modules/poll/poll.module
@@ -5,7 +5,7 @@
  * Collects votes on different topics in the form of multiple choice questions.
  */
 
-use Drupal\node\Node;
+use Drupal\node\Plugin\Core\Entity\Node;
 
 /**
  * Implements hook_help().
diff --git a/core/modules/rdf/lib/Drupal/rdf/Tests/TrackerAttributesTest.php b/core/modules/rdf/lib/Drupal/rdf/Tests/TrackerAttributesTest.php
index e4f6fe4..d92d106 100644
--- a/core/modules/rdf/lib/Drupal/rdf/Tests/TrackerAttributesTest.php
+++ b/core/modules/rdf/lib/Drupal/rdf/Tests/TrackerAttributesTest.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\rdf\Tests;
 
-use Drupal\node\Node;
+use Drupal\node\Plugin\Core\Entity\Node;
 use Drupal\simpletest\WebTestBase;
 
 /**
diff --git a/core/modules/search/search.module b/core/modules/search/search.module
index 315ae7a..a32b5c3 100644
--- a/core/modules/search/search.module
+++ b/core/modules/search/search.module
@@ -5,7 +5,7 @@
  * Enables site-wide keyword searching.
  */
 
-use Drupal\node\Node;
+use Drupal\node\Plugin\Core\Entity\Node;
 
 /**
  * Matches all 'N' Unicode character classes (numbers)
diff --git a/core/modules/statistics/statistics.module b/core/modules/statistics/statistics.module
index 8469e52..f11f3ed 100644
--- a/core/modules/statistics/statistics.module
+++ b/core/modules/statistics/statistics.module
@@ -5,7 +5,7 @@
  * Logs and displays access statistics for a site.
  */
 
-use Drupal\node\Node;
+use Drupal\node\Plugin\Core\Entity\Node;
 
 /**
  * Implements hook_help().
diff --git a/core/modules/system/tests/modules/entity_test/entity_test.module b/core/modules/system/tests/modules/entity_test/entity_test.module
index 46def82..357978f 100644
--- a/core/modules/system/tests/modules/entity_test/entity_test.module
+++ b/core/modules/system/tests/modules/entity_test/entity_test.module
@@ -9,21 +9,7 @@
  * Implements hook_entity_info().
  */
 function entity_test_entity_info() {
-  $items['entity_test'] = array(
-    'label' => t('Test entity'),
-    'entity class' => 'Drupal\entity_test\EntityTest',
-    'controller class' => 'Drupal\entity_test\EntityTestStorageController',
-    'form controller class' => array(
-      'default' => 'Drupal\entity_test\EntityTestFormController',
-    ),
-    'base table' => 'entity_test',
-    'data table' => 'entity_test_property_data',
-    'fieldable' => TRUE,
-    'entity keys' => array(
-      'id' => 'id',
-      'uuid' => 'uuid',
-    ),
-  );
+  $items['entity_test'] = array();
   // Optionally specify a translation handler for testing translations.
   if (variable_get('entity_test_translation')) {
     $items['entity_test']['translation']['entity_test'] = TRUE;
@@ -98,7 +84,7 @@ function entity_test_edit($entity) {
  * @param bool $reset
  *   A boolean indicating that the internal cache should be reset.
  *
- * @return Drupal\entity_test\EntityTest
+ * @return Drupal\entity_test\Plugin\Core\Entity\EntityTest
  *   The loaded entity object, or FALSE if the entity cannot be loaded.
  */
 function entity_test_load($id, $reset = FALSE) {
diff --git a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/EntityTest.php b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Plugin/Core/Entity/EntityTest.php
similarity index 59%
rename from core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/EntityTest.php
rename to core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Plugin/Core/Entity/EntityTest.php
index 17e8470..1aa1d2a 100644
--- a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/EntityTest.php
+++ b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Plugin/Core/Entity/EntityTest.php
@@ -2,15 +2,33 @@
 
 /**
  * @file
- * Definition of Drupal\entity_test\EntityTest.
+ * Definition of Drupal\entity_test\Plugin\Core\Entity\EntityTest.
  */
 
-namespace Drupal\entity_test;
+namespace Drupal\entity_test\Plugin\Core\Entity;
 
 use Drupal\Core\Entity\EntityNG;
+use Drupal\Core\Annotation\Plugin;
+use Drupal\Core\Annotation\Translation;
 
 /**
  * Defines the test entity class.
+ *
+ * @Plugin(
+ *   id = "entity_test",
+ *   label = @Translation("Test entity"),
+ *   controller_class = "Drupal\entity_test\EntityTestStorageController",
+ *   form_controller_class = {
+ *     "default" = "Drupal\entity_test\EntityTestFormController"
+ *   },
+ *   base_table = "entity_test",
+ *   data_table = "entity_test_property_data",
+ *   fieldable = TRUE,
+ *   entity_keys = {
+ *     "id" = "id",
+ *     "uuid" = "uuid"
+ *   }
+ * )
  */
 class EntityTest extends EntityNG {
 
diff --git a/core/modules/system/tests/modules/taxonomy_test/taxonomy_test.module b/core/modules/system/tests/modules/taxonomy_test/taxonomy_test.module
index 63f6406..b2e3adb 100644
--- a/core/modules/system/tests/modules/taxonomy_test/taxonomy_test.module
+++ b/core/modules/system/tests/modules/taxonomy_test/taxonomy_test.module
@@ -7,7 +7,7 @@
  * @see Drupal\taxonomy\Tests\TaxonomyHooksTestCase::testTaxonomyTermHooks()
  */
 
-use Drupal\taxonomy\Term;
+use Drupal\taxonomy\Plugin\Core\Entity\Term;
 
 /**
  * Implements hook_taxonomy_term_load().
diff --git a/core/modules/system/tests/modules/theme_page_test/theme_page_test.module b/core/modules/system/tests/modules/theme_page_test/theme_page_test.module
index fe86da9..63f8cb4 100644
--- a/core/modules/system/tests/modules/theme_page_test/theme_page_test.module
+++ b/core/modules/system/tests/modules/theme_page_test/theme_page_test.module
@@ -18,4 +18,4 @@ function theme_page_test_system_theme_info() {
   $themes['test_invalid_basetheme'] = drupal_get_path('module', 'system') . '/tests/themes/test_invalid_basetheme/test_invalid_basetheme.info';
   $themes['test_invalid_engine'] = drupal_get_path('module', 'system') . '/tests/themes/test_invalid_engine/test_invalid_engine.info';
   return $themes;
-}
\ No newline at end of file
+}
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Term.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Core/Entity/Term.php
similarity index 73%
rename from core/modules/taxonomy/lib/Drupal/taxonomy/Term.php
rename to core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Core/Entity/Term.php
index 42ad4c5..1dbf33c 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Term.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Core/Entity/Term.php
@@ -2,16 +2,36 @@
 
 /**
  * @file
- * Definition of Drupal\taxonomy\Term.
+ * Definition of Drupal\taxonomy\Plugin\Core\Entity\Term.
  */
 
-namespace Drupal\taxonomy;
+namespace Drupal\taxonomy\Plugin\Core\Entity;
 
 use Drupal\Core\Entity\ContentEntityInterface;
 use Drupal\Core\Entity\Entity;
+use Drupal\Core\Annotation\Plugin;
+use Drupal\Core\Annotation\Translation;
 
 /**
  * Defines the taxonomy term entity.
+ *
+ * @Plugin(
+ *   id = "taxonomy_term",
+ *   label = @Translation("Taxonomy term"),
+ *   controller_class = "Drupal\taxonomy\TermStorageController",
+ *   form_controller_class = {
+ *     "default" = "Drupal\taxonomy\TermFormController"
+ *   },
+ *   base_table = "taxonomy_term_data",
+ *   uri_callback = "taxonomy_term_uri",
+ *   fieldable = TRUE,
+ *   entity_keys = {
+ *     "id" = "tid",
+ *     "bundle" = "vocabulary_machine_name",
+ *     "label" = "name",
+ *     "uuid" = "uuid"
+ *   }
+ * )
  */
 class Term extends Entity implements ContentEntityInterface {
 
diff --git a/core/modules/taxonomy/taxonomy.admin.inc b/core/modules/taxonomy/taxonomy.admin.inc
index be305f6..8d03f7f 100644
--- a/core/modules/taxonomy/taxonomy.admin.inc
+++ b/core/modules/taxonomy/taxonomy.admin.inc
@@ -5,7 +5,7 @@
  * Administrative page callbacks for the taxonomy module.
  */
 
-use Drupal\taxonomy\Term;
+use Drupal\taxonomy\Plugin\Core\Entity\Term;
 use Drupal\taxonomy\Vocabulary;
 
 /**
diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module
index faa04dd..f539e5b 100644
--- a/core/modules/taxonomy/taxonomy.module
+++ b/core/modules/taxonomy/taxonomy.module
@@ -5,8 +5,8 @@
  * Enables the organization of content into categories.
  */
 
-use Drupal\node\Node;
-use Drupal\taxonomy\Term;
+use Drupal\node\Plugin\Core\Entity\Node;
+use Drupal\taxonomy\Plugin\Core\Entity\Term;
 use Drupal\taxonomy\Vocabulary;
 use Drupal\Core\Entity\EntityInterface;
 
@@ -111,21 +111,6 @@ function taxonomy_permission() {
 function taxonomy_entity_info() {
   $return = array(
     'taxonomy_term' => array(
-      'label' => t('Taxonomy term'),
-      'entity class' => 'Drupal\taxonomy\Term',
-      'controller class' => 'Drupal\taxonomy\TermStorageController',
-      'form controller class' => array(
-        'default' => 'Drupal\taxonomy\TermFormController',
-      ),
-      'base table' => 'taxonomy_term_data',
-      'uri callback' => 'taxonomy_term_uri',
-      'fieldable' => TRUE,
-      'entity keys' => array(
-        'id' => 'tid',
-        'bundle' => 'vocabulary_machine_name',
-        'label' => 'name',
-        'uuid' => 'uuid',
-      ),
       'bundle keys' => array(
         'bundle' => 'machine_name',
       ),
diff --git a/core/modules/taxonomy/taxonomy.pages.inc b/core/modules/taxonomy/taxonomy.pages.inc
index 7c77716..bcd4eab 100644
--- a/core/modules/taxonomy/taxonomy.pages.inc
+++ b/core/modules/taxonomy/taxonomy.pages.inc
@@ -5,7 +5,7 @@
  * Page callbacks for the taxonomy module.
  */
 
-use Drupal\taxonomy\Term;
+use Drupal\taxonomy\Plugin\Core\Entity\Term;
 use Drupal\taxonomy\Vocabulary;
 use Symfony\Component\HttpFoundation\JsonResponse;
 
diff --git a/core/modules/tracker/tracker.module b/core/modules/tracker/tracker.module
index 7060a87..8313269 100644
--- a/core/modules/tracker/tracker.module
+++ b/core/modules/tracker/tracker.module
@@ -5,7 +5,7 @@
  * Tracks recent content posted by a user or users.
  */
 
-use Drupal\node\Node;
+use Drupal\node\Plugin\Core\Entity\Node;
 
 /**
  * Implements hook_help().
diff --git a/core/modules/translation/lib/Drupal/translation/Tests/TranslationTest.php b/core/modules/translation/lib/Drupal/translation/Tests/TranslationTest.php
index a9fae77..453cbd2 100644
--- a/core/modules/translation/lib/Drupal/translation/Tests/TranslationTest.php
+++ b/core/modules/translation/lib/Drupal/translation/Tests/TranslationTest.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\translation\Tests;
 
-use Drupal\node\Node;
+use Drupal\node\Plugin\Core\Entity\Node;
 use Drupal\simpletest\WebTestBase;
 
 /**
diff --git a/core/modules/translation/tests/translation_test.module b/core/modules/translation/tests/translation_test.module
index 1bd0659..8c9fdf2 100644
--- a/core/modules/translation/tests/translation_test.module
+++ b/core/modules/translation/tests/translation_test.module
@@ -5,7 +5,7 @@
  * Mock module for content translation tests.
  */
 
-use Drupal\node\Node;
+use Drupal\node\Plugin\Core\Entity\Node;
 
 /**
  * Implements hook_node_insert().
diff --git a/core/modules/translation/translation.module b/core/modules/translation/translation.module
index bf1e528..3f2b62a 100644
--- a/core/modules/translation/translation.module
+++ b/core/modules/translation/translation.module
@@ -19,7 +19,7 @@
  *   date (0) or needs to be updated (1).
  */
 
-use Drupal\node\Node;
+use Drupal\node\Plugin\Core\Entity\Node;
 
 /**
  * Implements hook_help().
diff --git a/core/modules/translation/translation.pages.inc b/core/modules/translation/translation.pages.inc
index e33f53e..cc94a1e 100644
--- a/core/modules/translation/translation.pages.inc
+++ b/core/modules/translation/translation.pages.inc
@@ -5,7 +5,7 @@
  * User page callbacks for the Translation module.
  */
 
-use Drupal\node\Node;
+use Drupal\node\Plugin\Core\Entity\Node;
 
 /**
  * Page callback: Displays a list of a node's translations.
diff --git a/core/modules/user/lib/Drupal/user/User.php b/core/modules/user/lib/Drupal/user/Plugin/Core/Entity/User.php
similarity index 77%
rename from core/modules/user/lib/Drupal/user/User.php
rename to core/modules/user/lib/Drupal/user/Plugin/Core/Entity/User.php
index 2217588..18553e4 100644
--- a/core/modules/user/lib/Drupal/user/User.php
+++ b/core/modules/user/lib/Drupal/user/Plugin/Core/Entity/User.php
@@ -2,15 +2,35 @@
 
 /**
  * @file
- * Definition of Drupal\user\User.
+ * Definition of Drupal\user\Plugin\Core\Entity\User.
  */
 
-namespace Drupal\user;
+namespace Drupal\user\Plugin\Core\Entity;
 
 use Drupal\Core\Entity\Entity;
+use Drupal\Core\Annotation\Plugin;
+use Drupal\Core\Annotation\Translation;
 
 /**
  * Defines the user entity class.
+ *
+ * @Plugin(
+ *   id = "user",
+ *   label = @Translation("User"),
+ *   controller_class = "Drupal\user\UserStorageController",
+ *   form_controller_class = {
+ *     "profile" = "Drupal\user\ProfileFormController",
+ *     "register" = "Drupal\user\RegisterFormController"
+ *   },
+ *   base_table = "users",
+ *   uri_callback = "user_uri",
+ *   label_callback = "user_label",
+ *   fieldable = TRUE,
+ *   entity_keys = {
+ *     "id" = "uid",
+ *     "uuid" = "uuid"
+ *   }
+ * )
  */
 class User extends Entity {
 
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index e42002b..228343a 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -2,7 +2,7 @@
 
 use Drupal\Core\Database\Query\SelectInterface;
 use Drupal\Core\Entity\EntityInterface;
-use Drupal\file\File;
+use Drupal\file\Plugin\Core\Entity\File;
 use Drupal\Core\Template\Attribute;
 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
 
@@ -144,21 +144,6 @@ function user_theme() {
 function user_entity_info() {
   return array(
     'user' => array(
-      'label' => t('User'),
-      'controller class' => 'Drupal\user\UserStorageController',
-      'form controller class' => array(
-        'profile' => 'Drupal\user\ProfileFormController',
-        'register' => 'Drupal\user\RegisterFormController',
-      ),
-      'base table' => 'users',
-      'uri callback' => 'user_uri',
-      'label callback' => 'user_label',
-      'fieldable' => TRUE,
-      'entity class' => 'Drupal\user\User',
-      'entity keys' => array(
-        'id' => 'uid',
-        'uuid' => 'uuid',
-      ),
       'bundles' => array(
         'user' => array(
           'label' => t('User'),
