diff --git a/src/Plugin/Derivative/MigrateEntityReferenceRevisions.php b/src/Plugin/Derivative/MigrateEntityReferenceRevisions.php
new file mode 100644
index 0000000..2b8ae69
--- /dev/null
+++ b/src/Plugin/Derivative/MigrateEntityReferenceRevisions.php
@@ -0,0 +1,31 @@
+<?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
+ * @package Drupal\entity_reference_revisions\Plugin\Derivative
+ */
+class MigrateEntityReferenceRevisions extends MigrateEntityRevision  {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getDerivativeDefinitions($basePluginDefinition) {
+    foreach ($this->entityDefinitions as $entityType => $entityInfo) {
+      if ($entityInfo->getKey('revision')) {
+        $this->derivatives[$entityType] = array(
+          '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..b444233
--- /dev/null
+++ b/src/Plugin/migrate/destination/EntityReferenceRevisions.php
@@ -0,0 +1,140 @@
+<?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\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);
+      }
+
+      $entity = $this->storage->create($row->getDestination());
+      $entity->enforceIsNew();
+    }
+    $entity = $this->updateEntity($entity, $row) ?: $entity;
+    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($destination_identifiers[1]);
+    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($destination_identifiers[1]);
+    if ($entity) {
+      $entity->delete();
+    }
+  }
+}
diff --git a/tests/modules/err_migration_test/err_migration_test.info.yml b/tests/modules/err_migration_test/err_migration_test.info.yml
new file mode 100644
index 0000000..d61822b
--- /dev/null
+++ b/tests/modules/err_migration_test/err_migration_test.info.yml
@@ -0,0 +1,9 @@
+name: 'ERR migration test'
+type: module
+description: 'Entity migration test'
+package: Testing
+core: 8.x
+
+dependencies:
+ - entity_reference_revisions
+ - migrate
diff --git a/tests/modules/err_migration_test/migration_templates/err_migration_test.yml b/tests/modules/err_migration_test/migration_templates/err_migration_test.yml
new file mode 100644
index 0000000..e5d6d34
--- /dev/null
+++ b/tests/modules/err_migration_test/migration_templates/err_migration_test.yml
@@ -0,0 +1,12 @@
+id: err_migration_test
+migration_tags: {}
+label: 'ERR Migration Test'
+source:
+  plugin: err_dummy
+process:
+  id: id
+  revision_id: revision_id
+  name: name
+destination:
+  plugin: 'entity_reference_revisions:entity_test_composite'
+migration_dependencies: {  }
diff --git a/tests/modules/err_migration_test/src/Plugin/migrate/source/DummySource.php b/tests/modules/err_migration_test/src/Plugin/migrate/source/DummySource.php
new file mode 100644
index 0000000..3a13d00
--- /dev/null
+++ b/tests/modules/err_migration_test/src/Plugin/migrate/source/DummySource.php
@@ -0,0 +1,49 @@
+<?php
+
+namespace Drupal\err_migration_test\Plugin\migrate\source;
+
+use Drupal\migrate\Plugin\migrate\source\SourcePluginBase;
+
+/**
+ * @MigrateSource(
+ *   id = "err_dummy",
+ *   requirements_met = true
+ * )
+ */
+class DummySource extends SourcePluginBase  {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fields() {
+    return [];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function __toString() {
+    return 'Dummy source';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getIds() {
+    return [
+      'id' => [
+        'type' => 'integer',
+      ]
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function initializeIterator() {
+    return new \ArrayIterator([
+      ['id' => 1, 'revision_id' => 1, 'name' => 'content item 1'],
+      ['id' => '', 'revision_id' => '', 'name' => 'content item 2'],
+    ]);
+  }
+}
diff --git a/tests/src/Kernel/Plugin/Derivative/EntityReferenceRevisionsDeriverTest.php b/tests/src/Kernel/Plugin/Derivative/EntityReferenceRevisionsDeriverTest.php
new file mode 100644
index 0000000..d61b720
--- /dev/null
+++ b/tests/src/Kernel/Plugin/Derivative/EntityReferenceRevisionsDeriverTest.php
@@ -0,0 +1,49 @@
+<?php
+
+namespace Drupal\Tests\migrate\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', 'err_migration_test', 'entity_composite_relationship_test'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->installConfig($this->modules);
+  }
+
+  /**
+   * Tests deriver.
+   *
+   * @covers ::getDerivativeDefinitions
+   */
+  public function testDestinationDeriver() {
+    /** @var MigrationPluginManager $migrationManager */
+    $migrationManager = \Drupal::service('plugin.manager.migration');
+    /** @var MigrateDestinationPluginManager $migrationDestinationManager */
+    $migrationDestinationManager = \Drupal::service('plugin.manager.migrate.destination');
+
+    $definition = $migrationManager->getDefinition('err_migration_test');
+    $destination = $migrationDestinationManager->getDefinition($definition['destination']['plugin']);
+    $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..85cd928
--- /dev/null
+++ b/tests/src/Kernel/Plugin/migrate/destination/EntityReferenceRevisionsDestinationTest.php
@@ -0,0 +1,104 @@
+<?php
+
+namespace Drupal\Tests\migrate\Kernel\Plugin\migrate\destination;
+
+use Drupal\Core\Entity\EntityStorageBase;
+use Drupal\entity_reference_revisions\Plugin\migrate\destination\EntityReferenceRevisions;
+use Drupal\KernelTests\KernelTestBase;
+use Drupal\migrate\MigrateExecutable;
+use Drupal\migrate\MigrateMessageInterface;
+use Drupal\migrate\Plugin\Migration;
+use Drupal\migrate\Plugin\MigrationPluginManager;
+use Drupal\migrate\Plugin\MigrateDestinationPluginManager;
+
+/**
+ * Tests the migration plugin.
+ *
+ * @coversDefaultClass \Drupal\entity_reference_revisions\Plugin\migrate\destination\EntityReferenceRevisions
+ * @group entity_reference_revisions
+ */
+class EntityReferenceRevisionsDestinationTest extends KernelTestBase implements MigrateMessageInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = [
+    'migrate',
+    'err_migration_test',
+    'entity_reference_revisions',
+    'entity_composite_relationship_test',
+    'user',
+    'system',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->installEntitySchema('entity_test_composite');
+    $this->installSchema('system', ['sequences']);
+    $this->installConfig($this->modules);
+  }
+
+  /**
+   * Tests get entity type id.
+   *
+   * @covers ::getEntityTypeId
+   */
+  public function testGetEntityTypeId() {
+    /** @var MigrationPluginManager $migrationManager */
+    $migrationManager = \Drupal::service('plugin.manager.migration');
+    $definition = $migrationManager->getDefinition('err_migration_test');
+    /** @var Migration $migration */
+    $migration = $migrationManager->createStubMigration($definition);
+    /** @var EntityReferenceRevisions $destination */
+    $destination = $migration->getDestinationPlugin();
+
+    /** @var EntityStorageBase $storage */
+    $storage = $this->readAttribute($destination, 'storage');
+    $actual = $this->readAttribute($storage, 'entityTypeId');
+
+    $expected = 'entity_test_composite';
+    $this->assertEquals($expected, $actual);
+  }
+
+  /**
+   * Tests get entity.
+   *
+   * @covers ::getEntity
+   * @covers ::rollback
+   * @covers ::rollbackNonTranslation
+   */
+  public function testGetEntity() {
+    /** @var MigrationPluginManager $migrationManager */
+    $migrationManager = \Drupal::service('plugin.manager.migration');
+    $definition = $migrationManager->getDefinition('err_migration_test');
+    /** @var Migration $migration */
+    $migration = $migrationManager->createStubMigration($definition);
+    $migrationExecutable = (new MigrateExecutable($migration, $this));
+    /** @var EntityStorageBase $storage */
+    $storage = $this->readAttribute($migration->getDestinationPlugin(), 'storage');
+    for ($i = 0; $i < 2; $i++) {
+      $migrationExecutable->import();
+      $migration->getIdMap()->prepareUpdate();
+      $entity = $storage->loadRevision(1);
+      $this->assertEquals('content item 1', $entity->label());
+      $entity = $storage->loadRevision(2);
+      $this->assertEquals('content item 2', $entity->label());
+    }
+    $migrationExecutable->rollback();
+    $entity = $storage->loadRevision(1);
+    $this->assertEmpty($entity);
+    $entity = $storage->loadRevision(2);
+    $this->assertEmpty($entity);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function display($message, $type = 'status') {
+    $this->assertTrue($type == 'status', $message);
+  }
+
+}
