diff --git a/core/modules/comment/src/Plugin/migrate/destination/EntityComment.php b/core/modules/comment/src/Plugin/migrate/destination/EntityComment.php
index b370015dc6..a433c95704 100644
--- a/core/modules/comment/src/Plugin/migrate/destination/EntityComment.php
+++ b/core/modules/comment/src/Plugin/migrate/destination/EntityComment.php
@@ -3,6 +3,7 @@
 namespace Drupal\comment\Plugin\migrate\destination;
 
 use Drupal\Core\Entity\EntityManagerInterface;
+use Drupal\Core\Entity\EntityFieldManagerInterface;
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Core\Field\FieldTypePluginManagerInterface;
 use Drupal\Core\State\StateInterface;
@@ -53,9 +54,11 @@ class EntityComment extends EntityContentBase {
    *   The field type plugin manager service.
    * @param \Drupal\Core\State\StateInterface $state
    *   The state storage object.
+   *  @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
+   *   The entity field manager.
    */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles, EntityManagerInterface $entity_manager, FieldTypePluginManagerInterface $field_type_manager, StateInterface $state) {
-    parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $storage, $bundles, $entity_manager, $field_type_manager);
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles, EntityManagerInterface $entity_manager, FieldTypePluginManagerInterface $field_type_manager, StateInterface $state, EntityFieldManagerInterface $entity_field_manager = NULL) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $storage, $bundles, $entity_manager, $field_type_manager, $entity_field_manager);
     $this->state = $state;
   }
 
@@ -73,7 +76,8 @@ public static function create(ContainerInterface $container, array $configuratio
       array_keys($container->get('entity_type.bundle.info')->getBundleInfo($entity_type)),
       $container->get('entity.manager'),
       $container->get('plugin.manager.field.field_type'),
-      $container->get('state')
+      $container->get('state'),
+      $container->get('entity_field.manager')
     );
   }
 
diff --git a/core/modules/migrate/src/Plugin/migrate/destination/Entity.php b/core/modules/migrate/src/Plugin/migrate/destination/Entity.php
index a3b173f8d0..49fcc4a80d 100644
--- a/core/modules/migrate/src/Plugin/migrate/destination/Entity.php
+++ b/core/modules/migrate/src/Plugin/migrate/destination/Entity.php
@@ -152,7 +152,7 @@ public function getBundle(Row $row) {
    * {@inheritdoc}
    */
   public function fields(MigrationInterface $migration = NULL) {
-    // TODO: Implement fields() method.
+    return [];
   }
 
   /**
diff --git a/core/modules/migrate/src/Plugin/migrate/destination/EntityContentBase.php b/core/modules/migrate/src/Plugin/migrate/destination/EntityContentBase.php
index 079eed08e9..f68dbf1ab3 100644
--- a/core/modules/migrate/src/Plugin/migrate/destination/EntityContentBase.php
+++ b/core/modules/migrate/src/Plugin/migrate/destination/EntityContentBase.php
@@ -5,7 +5,9 @@
 use Drupal\Core\Entity\ContentEntityInterface;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityManagerInterface;
+use Drupal\Core\Entity\EntityFieldManagerInterface;
 use Drupal\Core\Entity\EntityStorageInterface;
+use Drupal\Core\Entity\FieldableEntityInterface;
 use Drupal\Core\Field\FieldTypePluginManagerInterface;
 use Drupal\Core\TypedData\TranslatableInterface;
 use Drupal\Core\TypedData\TypedDataInterface;
@@ -94,6 +96,13 @@ class EntityContentBase extends Entity implements HighestIdInterface {
    */
   protected $fieldTypeManager;
 
+  /**
+   * Field type plugin manager.
+   *
+   * @var \Drupal\Core\Entity\EntityFieldManagerInterface
+   */
+  protected $entityFieldManager;
+
   /**
    * Constructs a content entity.
    *
@@ -113,11 +122,14 @@ class EntityContentBase extends Entity implements HighestIdInterface {
    *   The entity manager service.
    * @param \Drupal\Core\Field\FieldTypePluginManagerInterface $field_type_manager
    *   The field type plugin manager service.
+   * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
+   *   The entity field manager.
    */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles, EntityManagerInterface $entity_manager, FieldTypePluginManagerInterface $field_type_manager) {
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles, EntityManagerInterface $entity_manager, FieldTypePluginManagerInterface $field_type_manager, EntityFieldManagerInterface $entity_field_manager = NULL) {
     parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $storage, $bundles);
     $this->entityManager = $entity_manager;
     $this->fieldTypeManager = $field_type_manager;
+    $this->entityFieldManager = $entity_field_manager;
   }
 
   /**
@@ -133,7 +145,8 @@ public static function create(ContainerInterface $container, array $configuratio
       $container->get('entity.manager')->getStorage($entity_type),
       array_keys($container->get('entity_type.bundle.info')->getBundleInfo($entity_type)),
       $container->get('entity.manager'),
-      $container->get('plugin.manager.field.field_type')
+      $container->get('plugin.manager.field.field_type'),
+      $container->get('entity_field.manager')
     );
   }
 
@@ -366,4 +379,26 @@ public function getHighestId() {
     return (int) current($values);
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function fields(MigrationInterface $migration = NULL) {
+    $entity_type_id = self::getEntityTypeId($this->getPluginId());
+    $entity_type = $this->entityManager->getDefinition($entity_type_id);
+    // Retrieving fields from a non-fieldable content entity will return a
+    // LogicException. Return an empty list of fields instead.
+    if (!$entity_type->entityClassImplements(FieldableEntityInterface::class)) {
+      return [];
+    }
+    $field_definitions = $this->entityFieldManager->getBaseFieldDefinitions($entity_type->id());
+    if (!empty($this->configuration['default_bundle'])) {
+      $field_definitions += $this->entityFieldManager->getFieldDefinitions($entity_type->id(), $this->configuration['default_bundle']);
+    }
+    $fields = [];
+    foreach ($field_definitions as $field_name => $definition) {
+      $fields[$field_name] = (string) $definition->getLabel();
+    }
+    return $fields;
+  }
+
 }
diff --git a/core/modules/migrate/tests/modules/migrate_destination_test/migrate_destination_test.info.yml b/core/modules/migrate/tests/modules/migrate_destination_test/migrate_destination_test.info.yml
new file mode 100644
index 0000000000..d8f21fb642
--- /dev/null
+++ b/core/modules/migrate/tests/modules/migrate_destination_test/migrate_destination_test.info.yml
@@ -0,0 +1,6 @@
+name: 'Migrate module destination tests'
+type: module
+description: 'Support module destination testing.'
+package: Testing
+version: VERSION
+core: 8.x
diff --git a/core/modules/migrate/tests/modules/migrate_destination_test/migrations/node_no_fields.yml b/core/modules/migrate/tests/modules/migrate_destination_test/migrations/node_no_fields.yml
new file mode 100644
index 0000000000..76fda32c21
--- /dev/null
+++ b/core/modules/migrate/tests/modules/migrate_destination_test/migrations/node_no_fields.yml
@@ -0,0 +1,11 @@
+id: node_no_fields
+label: Migrate to no bundle specified destination
+source:
+  plugin: migrate_destination_test
+  constants:
+    type: test_node_type_no_fields
+process:
+  type: constants/type
+  title: title
+destination:
+  plugin: entity:node
diff --git a/core/modules/migrate/tests/modules/migrate_destination_test/migrations/node_with_fields.yml b/core/modules/migrate/tests/modules/migrate_destination_test/migrations/node_with_fields.yml
new file mode 100644
index 0000000000..b1ba2fa9ff
--- /dev/null
+++ b/core/modules/migrate/tests/modules/migrate_destination_test/migrations/node_with_fields.yml
@@ -0,0 +1,12 @@
+id: node_with_fields
+label: Migrate to bundle specified destination
+source:
+  plugin: migrate_destination_test
+  constants:
+    type: test_node_type_with_fields
+process:
+  type: constants/type
+  title: title
+destination:
+  plugin: entity:node
+  default_bundle: test_node_type_with_fields
diff --git a/core/modules/migrate/tests/modules/migrate_destination_test/src/Plugin/migrate/source/MigrateDestinationTestSource.php b/core/modules/migrate/tests/modules/migrate_destination_test/src/Plugin/migrate/source/MigrateDestinationTestSource.php
new file mode 100644
index 0000000000..45c45f631a
--- /dev/null
+++ b/core/modules/migrate/tests/modules/migrate_destination_test/src/Plugin/migrate/source/MigrateDestinationTestSource.php
@@ -0,0 +1,63 @@
+<?php
+
+namespace Drupal\migrate_destination_test\Plugin\migrate\source;
+
+use Drupal\migrate\Plugin\migrate\source\SourcePluginBase;
+
+/**
+ * A simple migrate source for our tests.
+ *
+ * @MigrateSource(
+ *   id = "migrate_destination_test"
+ * )
+ */
+class MigrateDestinationTestSource extends SourcePluginBase {
+
+  /**
+   * The data to import.
+   *
+   * @var array
+   */
+  protected $import = [
+    ['title' => 'Cat'],
+    ['title' => 'Dog'],
+    ['title' => 'Monkey'],
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fields() {
+    return [
+      'title' => $this->t('Title'),
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function __toString() {
+    return '';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getIds() {
+    $ids['title']['type'] = 'string';
+    return $ids;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function initializeIterator() {
+    $data = [];
+    foreach ($this->import as $row) {
+      $data[] = $row;
+    }
+
+    return new \ArrayIterator($data);
+  }
+
+}
diff --git a/core/modules/migrate/tests/src/Kernel/MigrateEntityDestinationTest.php b/core/modules/migrate/tests/src/Kernel/MigrateEntityDestinationTest.php
new file mode 100644
index 0000000000..a418fabe5b
--- /dev/null
+++ b/core/modules/migrate/tests/src/Kernel/MigrateEntityDestinationTest.php
@@ -0,0 +1,84 @@
+<?php
+
+namespace Drupal\Tests\migrate\Kernel;
+
+use Drupal\field\Entity\FieldConfig;
+use Drupal\field\Entity\FieldStorageConfig;
+use Drupal\node\Entity\NodeType;
+
+/**
+ * Tests the destination Entity plugin.
+ *
+ * @group migrate
+ */
+class MigrateEntityDestinationTest extends MigrateTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = [
+    'system',
+    'user',
+    'node',
+    'field',
+    'migrate_destination_test',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp() {
+    parent::setUp();
+    $this->installSchema('system', ['sequences']);
+    $this->installSchema('node', ['node_access']);
+    $this->installEntitySchema('user');
+    $this->installEntitySchema('node');
+
+    NodeType::create([
+      'type' => 'test_node_type_no_field',
+      'name' => 'Test node type without fields',
+    ])->save();
+
+    NodeType::create([
+      'type' => 'test_node_type_with_fields',
+      'name' => 'Test node type with fields',
+    ])->save();
+  }
+
+  /**
+   * Test destination fields() method.
+   */
+  public function testDestinationField() {
+    $node_with_fields = $this->getMigration('node_with_fields');
+    $destination_fields = $node_with_fields->getDestinationPlugin();
+
+    $node_no_fields = $this->getMigration('node_no_fields');
+    $destination_no_fields = $node_no_fields->getDestinationPlugin();
+
+    $this->assertTrue(in_array('nid', array_keys($destination_fields->fields())));
+    $this->assertFalse(in_array('field_text', array_keys($destination_fields->fields())));
+
+    $this->assertTrue(in_array('nid', array_keys($destination_no_fields->fields())));
+    $this->assertFalse(in_array('field_text', array_keys($destination_no_fields->fields())));
+
+    // Create a text field attached to 'test_node_type_2' node-type.
+    FieldStorageConfig::create([
+      'type' => 'string',
+      'entity_type' => 'node',
+      'field_name' => 'field_text',
+    ])->save();
+
+    FieldConfig::create([
+      'entity_type' => 'node',
+      'bundle' => 'test_node_type_with_fields',
+      'field_name' => 'field_text',
+    ])->save();
+
+    $this->assertTrue(in_array('field_text', array_keys($destination_fields->fields())));
+    // The destination_bundle_entity migration has default bundle of
+    // test_node_type so it shouldn't show the fields on other node types.
+    $this->assertFalse(in_array('field_text', array_keys($destination_no_fields->fields())));
+
+  }
+
+}
diff --git a/core/modules/user/src/Plugin/migrate/destination/EntityUser.php b/core/modules/user/src/Plugin/migrate/destination/EntityUser.php
index da867423ea..277e632532 100644
--- a/core/modules/user/src/Plugin/migrate/destination/EntityUser.php
+++ b/core/modules/user/src/Plugin/migrate/destination/EntityUser.php
@@ -3,6 +3,7 @@
 namespace Drupal\user\Plugin\migrate\destination;
 
 use Drupal\Core\Entity\ContentEntityInterface;
+use Drupal\Core\Entity\EntityFieldManagerInterface;
 use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Core\Field\FieldTypePluginManagerInterface;
@@ -95,9 +96,11 @@ class EntityUser extends EntityContentBase {
    *   The field type plugin manager service.
    * @param \Drupal\Core\Password\PasswordInterface $password
    *   The password service.
+   * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
+   *   The entity field manager.
    */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles, EntityManagerInterface $entity_manager, FieldTypePluginManagerInterface $field_type_manager, PasswordInterface $password) {
-    parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $storage, $bundles, $entity_manager, $field_type_manager);
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles, EntityManagerInterface $entity_manager, FieldTypePluginManagerInterface $field_type_manager, PasswordInterface $password, EntityFieldManagerInterface $entity_field_manager = NULL) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $storage, $bundles, $entity_manager, $field_type_manager, $entity_field_manager);
     $this->password = $password;
   }
 
@@ -115,7 +118,8 @@ public static function create(ContainerInterface $container, array $configuratio
       array_keys($container->get('entity_type.bundle.info')->getBundleInfo($entity_type)),
       $container->get('entity.manager'),
       $container->get('plugin.manager.field.field_type'),
-      $container->get('password')
+      $container->get('password'),
+      $container->get('entity_field.manager')
     );
   }
 
