diff --git a/src/Plugin/Derivative/MigrateEntityReferenceRevisions.php b/src/Plugin/Derivative/MigrateEntityReferenceRevisions.php
new file mode 100644
index 0000000..bb7d0c2
--- /dev/null
+++ b/src/Plugin/Derivative/MigrateEntityReferenceRevisions.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace Drupal\entity_reference_revisions\Plugin\Derivative;
+
+use Drupal\entity_reference_revisions\Plugin\migrate\destination\EntityReferenceRevisions;
+use Drupal\migrate\Plugin\Derivative\MigrateEntityRevision;
+
+/**
+ * Class MigrateEntityReferenceRevisions
+ */
+class MigrateEntityReferenceRevisions extends MigrateEntityRevision  {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getDerivativeDefinitions($basePluginDefinition) {
+    foreach ($this->entityDefinitions as $entityType => $entityInfo) {
+      if ($entityInfo->getKey('revision')) {
+        $this->derivatives[$entityType] = [
+          'id' => "entity_reference_revisions:$entityType",
+          'class' => EntityReferenceRevisions::class,
+          'requirements_met' => 1,
+          'provider' => $entityInfo->getProvider(),
+        ];
+      }
+    }
+    return $this->derivatives;
+  }
+
+}
diff --git a/src/Plugin/migrate/destination/EntityReferenceRevisions.php b/src/Plugin/migrate/destination/EntityReferenceRevisions.php
new file mode 100644
index 0000000..d41f27a
--- /dev/null
+++ b/src/Plugin/migrate/destination/EntityReferenceRevisions.php
@@ -0,0 +1,147 @@
+<?php
+
+namespace Drupal\entity_reference_revisions\Plugin\migrate\destination;
+
+use Drupal\Core\Entity\ContentEntityInterface;
+use Drupal\Core\TypedData\TranslatableInterface;
+use Drupal\migrate\MigrateException;
+use Drupal\migrate\Plugin\migrate\destination\EntityRevision;
+use Drupal\migrate\Plugin\MigrateIdMapInterface;
+use Drupal\migrate\Row;
+
+/**
+ * Provides entity_reference_revisions destination plugin.
+ *
+ * @MigrateDestination(
+ *   id = "entity_reference_revisions",
+ *   deriver = "Drupal\entity_reference_revisions\Plugin\Derivative\MigrateEntityReferenceRevisions"
+ * )
+ */
+class EntityReferenceRevisions extends EntityRevision {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static function getEntityTypeId($pluginId) {
+    // Remove "entity_reference_revisions:".
+    // Ideally, we would call getDerivativeId(), but since this is static
+    // that is not possible so we follow the same pattern as core.
+    return substr($pluginId, 27);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function save(ContentEntityInterface $entity, array $oldDestinationIdValues = array()) {
+    $entity->save();
+
+    return [
+      $this->getKey('id') => $entity->id(),
+      $this->getKey('revision') => $entity->getRevisionId(),
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getIds() {
+    if ($revision_key = $this->getKey('revision')) {
+      $id_key = $this->getKey('id');
+      $ids[$id_key]['type'] = 'integer';
+
+      // TODO: Improve after https://www.drupal.org/node/2783715 is finished.
+      $ids[$revision_key]['type'] = 'integer';
+
+      if ($this->isTranslationDestination()) {
+        if ($revision_key = $this->getKey('langcode')) {
+          $ids[$revision_key]['type'] = 'string';
+        }
+        else {
+          throw new MigrateException('This entity type does not support translation.');
+        }
+      }
+
+      return $ids;
+    }
+    throw new MigrateException('This entity type does not support revisions.');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getEntity(Row $row, array $oldDestinationIdValues) {
+    $revision_id = $oldDestinationIdValues ?
+      array_pop($oldDestinationIdValues) :
+      $row->getDestinationProperty($this->getKey('revision'));
+    if (!empty($revision_id) && ($entity = $this->storage->loadRevision($revision_id))) {
+      $entity->setNewRevision(FALSE);
+    }
+    else {
+      // Attempt to ensure we always have a bundle.
+      if ($bundle = $this->getBundle($row)) {
+        $row->setDestinationProperty($this->getKey('bundle'), $bundle);
+      }
+
+      // Stubs might need some required fields filled in.
+      if ($row->isStub()) {
+        $this->processStubRow($row);
+      }
+      $entity = $this->storage->create($row->getDestination())
+        ->enforceIsNew(TRUE);
+      $entity->setNewRevision(TRUE);
+    }
+    $entity = $this->updateEntity($entity, $row) ?: $entity;
+    $this->rollbackAction = MigrateIdMapInterface::ROLLBACK_DELETE;
+    return $entity;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function rollback(array $destination_identifiers) {
+    if ($this->isTranslationDestination()) {
+      $this->rollbackTranslation($destination_identifiers);
+    }
+    else {
+      $this->rollbackNonTranslation($destination_identifiers);
+    }
+  }
+
+  /**
+   * Rollback translation destinations.
+   *
+   * @param array $destination_identifiers
+   *   The IDs of the destination object to delete.
+   */
+  protected function rollbackTranslation(array $destination_identifiers) {
+    $entity = $this->storage->loadRevision(array_pop($destination_identifiers));
+    if ($entity && $entity instanceof TranslatableInterface) {
+      if ($key = $this->getKey('langcode')) {
+        if (isset($destination_identifier[$key])) {
+          $langcode = $destination_identifier[$key];
+          if ($entity->hasTranslation($langcode)) {
+            // Make sure we don't remove the default translation.
+            $translation = $entity->getTranslation($langcode);
+            if (!$translation->isDefaultTranslation()) {
+              $entity->removeTranslation($langcode);
+              $entity->save();
+            }
+          }
+        }
+      }
+    }
+  }
+
+  /**
+   * Rollback non-translation destinations.
+   *
+   * @param array $destination_identifiers
+   *   The IDs of the destination object to delete.
+   */
+  protected function rollbackNonTranslation(array $destination_identifiers) {
+    $entity = $this->storage->loadRevision(array_pop($destination_identifiers));
+    if ($entity) {
+      $entity->delete();
+    }
+  }
+}
diff --git a/tests/src/Kernel/Plugin/Derivative/EntityReferenceRevisionsDeriverTest.php b/tests/src/Kernel/Plugin/Derivative/EntityReferenceRevisionsDeriverTest.php
new file mode 100644
index 0000000..e68cf05
--- /dev/null
+++ b/tests/src/Kernel/Plugin/Derivative/EntityReferenceRevisionsDeriverTest.php
@@ -0,0 +1,46 @@
+<?php
+
+namespace Drupal\Tests\entity_reference_revisions\Kernel\Plugin\Derivative;
+
+use Drupal\entity_reference_revisions\Plugin\migrate\destination\EntityReferenceRevisions;
+use Drupal\KernelTests\KernelTestBase;
+use Drupal\migrate\Plugin\MigrationPluginManager;
+use Drupal\migrate\Plugin\MigrateDestinationPluginManager;
+
+/**
+ * Tests the migration deriver.
+ *
+ * @coversDefaultClass \Drupal\entity_reference_revisions\Plugin\Derivative\MigrateEntityReferenceRevisions
+ * @group entity_reference_revisions
+ */
+class EntityReferenceRevisionsDeriverTest extends KernelTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['migrate', 'entity_reference_revisions', 'entity_composite_relationship_test'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->installConfig($this->modules);
+  }
+
+  /**
+   * Tests deriver.
+   *
+   * @covers ::getDerivativeDefinitions
+   */
+  public function testDestinationDeriver() {
+    /** @var MigrateDestinationPluginManager $migrationDestinationManager */
+    $migrationDestinationManager = \Drupal::service('plugin.manager.migrate.destination');
+
+    $destination = $migrationDestinationManager->getDefinition('entity_reference_revisions:entity_test_composite');
+    $this->assertEquals(EntityReferenceRevisions::class, $destination['class']);
+  }
+
+
+
+}
diff --git a/tests/src/Kernel/Plugin/migrate/destination/EntityReferenceRevisionsDestinationTest.php b/tests/src/Kernel/Plugin/migrate/destination/EntityReferenceRevisionsDestinationTest.php
new file mode 100644
index 0000000..c7768d4
--- /dev/null
+++ b/tests/src/Kernel/Plugin/migrate/destination/EntityReferenceRevisionsDestinationTest.php
@@ -0,0 +1,484 @@
+<?php
+
+namespace Drupal\Tests\entity_reference_revisions\Kernel\Plugin\migrate\destination;
+
+use Drupal\Core\Entity\EntityStorageBase;
+use Drupal\entity_reference_revisions\Plugin\migrate\destination\EntityReferenceRevisions;
+use Drupal\field\Entity\FieldConfig;
+use Drupal\field\Entity\FieldStorageConfig;
+use Drupal\KernelTests\KernelTestBase;
+use Drupal\migrate\MigrateExecutable;
+use Drupal\migrate\MigrateMessageInterface;
+use Drupal\migrate\Plugin\Migration;
+use Drupal\node\Entity\NodeType;
+
+/**
+ * Tests the migration destination plugin.
+ *
+ * @coversDefaultClass \Drupal\entity_reference_revisions\Plugin\migrate\destination\EntityReferenceRevisions
+ * @group entity_reference_revisions
+ */
+class EntityReferenceRevisionsDestinationTest extends KernelTestBase implements MigrateMessageInterface {
+
+  /**
+   * @var \Drupal\migrate\Plugin\MigrationPluginManager $migrationManager
+   *
+   * The migration plugin manager.
+   */
+  protected $migrationPluginManager;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = [
+    'migrate',
+    'entity_reference_revisions',
+    'entity_composite_relationship_test',
+    'user',
+    'system',
+    'text',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->installEntitySchema('entity_test_composite');
+    $this->installSchema('system', ['sequences']);
+    $this->installConfig($this->modules);
+
+    $this->migrationPluginManager = \Drupal::service('plugin.manager.migration');
+  }
+
+  /**
+   * Tests get entity type id.
+   *
+   * @dataProvider getEntityTypeIdDataProvider
+   *
+   * @covers ::getEntityTypeId
+   */
+  public function testGetEntityTypeId(array $definition, $expected) {
+    /** @var Migration $migration */
+    $migration = $this->migrationPluginManager->createStubMigration($definition);
+    /** @var EntityReferenceRevisions $destination */
+    $destination = $migration->getDestinationPlugin();
+
+    /** @var EntityStorageBase $storage */
+    $storage = $this->readAttribute($destination, 'storage');
+    $actual = $this->readAttribute($storage, 'entityTypeId');
+
+    $this->assertEquals($expected, $actual);
+  }
+
+  /**
+   * Provides multiple migration definitions for "getEntityTypeId" test.
+   */
+  public function getEntityTypeIdDataProvider() {
+    $datas  = $this->getEntityDataProvider();
+
+    foreach ($datas as &$data) {
+      $data['expected'] = 'entity_test_composite';
+    }
+
+    return $datas;
+  }
+
+  /**
+   * Tests get entity.
+   *
+   * @dataProvider getEntityDataProvider
+   *
+   * @covers ::getEntity
+   * @covers ::rollback
+   * @covers ::rollbackNonTranslation
+   */
+  public function testGetEntity(array $definition, array $expected) {
+    /** @var Migration $migration */
+    $migration = $this->migrationPluginManager->createStubMigration($definition);
+    $migrationExecutable = (new MigrateExecutable($migration, $this));
+    /** @var EntityStorageBase $storage */
+    $storage = $this->readAttribute($migration->getDestinationPlugin(), 'storage');
+    // Test inserting and updating by looping twice.
+    for ($i = 0; $i < 2; $i++) {
+      $migrationExecutable->import();
+      $migration->getIdMap()->prepareUpdate();
+      foreach ($expected as $data) {
+        $entity = $storage->loadRevision($data['id']);
+        $this->assertEquals($data['label'], $entity->label());
+      }
+    }
+    $migrationExecutable->rollback();
+    foreach ($expected as $data) {
+      $entity = $storage->loadRevision($data['id']);
+      $this->assertEmpty($entity);
+    }
+  }
+
+  /**
+   * Provides multiple migration definitions for "getEntity" test.
+   */
+  public function getEntityDataProvider() {
+    return [
+      'without keys' => [
+        'definition' => [
+          'source' => [
+            'plugin' => 'embedded_data',
+            'data_rows' => [
+              ['id' => 1, 'name' => 'content item 1a'],
+              ['id' => 1, 'name' => 'content item 1b'],
+              ['id' => 2, 'name' => 'content item 2'],
+            ],
+            'ids' => [
+              'id' => ['type' => 'integer'],
+              'name' => ['type' => 'text'],
+            ],
+          ],
+          'process' => [
+            'name' => 'name',
+          ],
+          'destination' => [
+            'plugin' => 'entity_reference_revisions:entity_test_composite',
+          ],
+        ],
+        'expected' => [
+          ['id' => 1, 'label' => 'content item 1a'],
+          ['id' => 2, 'label' => 'content item 1b'],
+          ['id' => 3, 'label' => 'content item 2'],
+        ],
+      ],
+      'with keys' => [
+        'definition' => [
+          'source' => [
+            'plugin' => 'embedded_data',
+            'data_rows' => [
+              ['id' => 1, 'revision_id' => 1, 'name' => 'content item 1'],
+              ['id' => 2, 'revision_id' => 2, 'name' => 'content item 2'],
+              ['id' => 3, 'revision_id' => 3, 'name' => 'content item 3'],
+            ],
+            'ids' => [
+              'id' => ['type' => 'integer'],
+              'name' => ['type' => 'text'],
+            ],
+          ],
+          'process' => [
+            'id' => 'id',
+            'revision_id' => 'revision_id',
+            'name' => 'name',
+          ],
+          'destination' => [
+            'plugin' => 'entity_reference_revisions:entity_test_composite',
+          ],
+        ],
+        'expected' => [
+          ['id' => 1, 'label' => 'content item 1'],
+          ['id' => 2, 'label' => 'content item 2'],
+          ['id' => 3, 'label' => 'content item 3'],
+        ],
+      ],
+    ];
+  }
+
+  /**
+   * Tests multi-value and single-value destination field linkage.
+   *
+   * @dataProvider destinationFieldMappingDataProvider
+   *
+   */
+  public function testDestinationFieldMapping(array $datas) {
+    $this->enableModules(['node', 'field']);
+    $this->installEntitySchema('node');
+    $this->installEntitySchema('user');
+    $this->installSchema('node', ['node_access']);
+
+    // Create new content type.
+    $values = ['type' => 'article', 'name' => 'Article'];
+    $node_type = NodeType::create($values);
+    $node_type->save();
+
+    // Add the field_err_single field to the node type.
+    $field_storage = FieldStorageConfig::create([
+      'field_name' => 'field_err_single',
+      'entity_type' => 'node',
+      'type' => 'entity_reference_revisions',
+      'settings' => [
+        'target_type' => 'entity_test_composite'
+      ],
+      'cardinality' => 1,
+    ]);
+    $field_storage->save();
+    $field = FieldConfig::create([
+      'field_storage' => $field_storage,
+      'bundle' => 'article',
+    ]);
+    $field->save();
+
+    // Add the field_err_multiple field to the node type.
+    $field_storage = FieldStorageConfig::create([
+      'field_name' => 'field_err_multiple',
+      'entity_type' => 'node',
+      'type' => 'entity_reference_revisions',
+      'settings' => [
+        'target_type' => 'entity_test_composite'
+      ],
+      'cardinality' => -1,
+    ]);
+    $field_storage->save();
+    $field = FieldConfig::create([
+      'field_storage' => $field_storage,
+      'bundle' => 'article',
+    ]);
+    $field->save();
+
+    $definitions = [];
+    $instances = [];
+    foreach ($datas as $data) {
+      $definitions[$data['definition']['id']] = $data['definition'];
+      $instances[$data['definition']['id']] = $this->migrationPluginManager->createStubMigration($data['definition']);
+    }
+
+    // Reflection is easier than mocking. We need to use createInstance for
+    // purposes of registering the migration for the migration process plugin.
+    $reflector = new \ReflectionObject($this->migrationPluginManager);
+    $property = $reflector->getProperty('definitions');
+    $property->setAccessible(TRUE);
+    $property->setValue($this->migrationPluginManager, $definitions);
+    $this->container->set('plugin.manager.migration', $this->migrationPluginManager);
+
+    foreach ($datas as $data) {
+      $migration = $this->migrationPluginManager->createInstance($data['definition']['id']);
+      $migrationExecutable = (new MigrateExecutable($migration, $this));
+      /** @var EntityStorageBase $storage */
+      $storage = $this->readAttribute($migration->getDestinationPlugin(), 'storage');
+      $migrationExecutable->import();
+      foreach ($data['expected'] as $expected) {
+        $entity = $storage->load($expected['id']);
+        $properties = array_diff_key($expected, array_flip(['id']));
+        foreach ($properties as $property => $value) {
+          if (is_array($value)) {
+            foreach ($value as $delta => $text) {
+              $this->assertNotEmpty($entity->{$property}[$delta]->entity, "Entity property $property with $delta is not empty");
+              $this->assertEquals($text, $entity->{$property}[$delta]->entity->label());
+            }
+          }
+          else {
+            $this->assertNotEmpty($entity, $expected[$property] .' is not empty');
+            $this->assertEquals($expected[$property], $entity->label());
+          }
+        }
+      }
+    }
+  }
+
+  /**
+   * Provides multiple migration definitions for "getEntity" test.
+   */
+  public function destinationFieldMappingDataProvider() {
+    return [
+      'scenario 1' => [
+        [
+          'single err' => [
+            'definition' => [
+              'id' => 'single_err',
+              'class' => Migration::class,
+              'source' => [
+                'plugin' => 'embedded_data',
+                'data_rows' => [
+                  [
+                    'id' => 1,
+                    'photo' => 'Photo1 here',
+                  ],
+                  [
+                    'id' => 2,
+                    'photo' => 'Photo2 here',
+                  ],
+                ],
+                'ids' => [
+                  'id' => ['type' => 'integer'],
+                ],
+              ],
+              'process' => [
+                'name' => 'photo',
+              ],
+              'destination' => [
+                'plugin' => 'entity_reference_revisions:entity_test_composite',
+              ],
+            ],
+            'expected' => [
+              ['id' => 1, 'name' => 'Photo1 here'],
+              ['id' => 2, 'name' => 'Photo2 here'],
+            ],
+          ],
+          'multiple err author1' => [
+            'definition' => [
+              'id' => 'multiple_err_author1',
+              'class' => Migration::class,
+              'source' => [
+                'plugin' => 'embedded_data',
+                'data_rows' => [
+                  [
+                    'id' => 1,
+                    'author' => 'Author 1',
+                  ],
+                  [
+                    'id' => 2,
+                    'author' => 'Author 2',
+                  ],
+                ],
+                'ids' => [
+                  'author' => ['type' => 'text'],
+                ],
+              ],
+              'process' => [
+                'name' => 'author',
+              ],
+              'destination' => [
+                'plugin' => 'entity_reference_revisions:entity_test_composite',
+              ],
+            ],
+            'expected' => [
+              ['id' => 3, 'name' => 'Author 1'],
+              ['id' => 4, 'name' => 'Author 2'],
+            ],
+          ],
+          'multiple err author 2' => [
+            'definition' => [
+              'id' => 'multiple_err_author2',
+              'class' => Migration::class,
+              'source' => [
+                'plugin' => 'embedded_data',
+                'data_rows' => [
+                  [
+                    'id' => 1,
+                    'author' => 'Author 3',
+                  ],
+                  [
+                    'id' => 2,
+                    'author' => 'Author 4',
+                  ],
+                ],
+                'ids' => [
+                  'author' => ['type' => 'text'],
+                ],
+              ],
+              'process' => [
+                'name' => 'author',
+              ],
+              'destination' => [
+                'plugin' => 'entity_reference_revisions:entity_test_composite',
+              ],
+            ],
+            'expected' => [
+              ['id' => 5, 'name' => 'Author 3'],
+              ['id' => 6, 'name' => 'Author 4'],
+            ],
+          ],
+          'destination entity' => [
+            'definition' => [
+              'id' => 'node_migration',
+              'class' => Migration::class,
+              'source' => [
+                'plugin' => 'embedded_data',
+                'data_rows' => [
+                  [
+                    'id' => 1,
+                    'title' => 'Article 1',
+                    'photo' => 'Photo1 here',
+                    'author' => ['Author 1', 'Author 3'],
+                  ],
+                  [
+                    'id' => 2,
+                    'title' => 'Article 2',
+                    'photo' => 'Photo2 here',
+                    'author' => ['Author 2', 'Author 4'],
+                  ],
+                ],
+                'ids' => [
+                  'id' => ['type' => 'integer'],
+                ],
+              ],
+              'process' => [
+                'title' => 'title',
+                'type' => [
+                  'plugin' => 'default_value',
+                  'default_value' => 'article',
+                ],
+                'field_err_single/target_id' => [
+                  [
+                    'plugin' => 'migration',
+                    'migration' => ['single_err'],
+                    'no_stub' => TRUE,
+                    'source' => 'id',
+                  ],
+                  [
+                    'plugin' => 'extract',
+                    'index' => [
+                      '0',
+                    ],
+                  ],
+                ],
+                'field_err_single/target_revision_id' => [
+                  [
+                    'plugin' => 'migration',
+                    'migration' => ['single_err'],
+                    'no_stub' => TRUE,
+                    'source' => 'id',
+                  ],
+                  [
+                    'plugin' => 'extract',
+                    'index' => [
+                      1,
+                    ],
+                  ],
+                ],
+                'field_err_multiple' => [
+                  [
+                    'plugin' => 'migration',
+                    'migration' => [
+                      'multiple_err_author1',
+                      'multiple_err_author2',
+                    ],
+                    'no_stub' => TRUE,
+                    'source' => 'author',
+                  ],
+                  [
+                    'plugin' => 'iterator',
+                    'process' => [
+                      'target_id' => '0',
+                      'target_revision_id' => '1',
+                    ],
+                  ],
+                ],
+              ],
+              'destination' => [
+                'plugin' => 'entity:node',
+              ],
+            ],
+            'expected' => [
+              [
+                'id' => 1,
+                'title' => 'Article 1',
+                'field_err_single' => ['Photo1 here'],
+                'field_err_multiple' => ['Author 1', 'Author 3'],
+              ],
+              [
+                'id' => 2,
+                'title' => 'Article 2',
+                'field_err_single' => ['Photo2 here'],
+                'field_err_multiple' => ['Author 2', 'Author 4'],
+              ],
+            ],
+          ],
+        ],
+      ],
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function display($message, $type = 'status') {
+    $this->assertTrue($type == 'status', $message);
+  }
+
+}
