diff --git a/core/modules/block/src/Plugin/migrate/process/BlockPluginId.php b/core/modules/block/src/Plugin/migrate/process/BlockPluginId.php
index b14ca5506ce7ed088305ab3af2724437eb6f1575..7d951012a02fabc478584ac449dc74f9e32227f9 100644
--- a/core/modules/block/src/Plugin/migrate/process/BlockPluginId.php
+++ b/core/modules/block/src/Plugin/migrate/process/BlockPluginId.php
@@ -4,6 +4,7 @@
 
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\migrate\MigrateLookupInterface;
 use Drupal\migrate\Plugin\MigrationInterface;
 use Drupal\migrate\MigrateExecutableInterface;
 use Drupal\migrate\Plugin\MigrateProcessInterface;
@@ -19,13 +20,27 @@
 class BlockPluginId extends ProcessPluginBase implements ContainerFactoryPluginInterface {
 
   /**
-   * The migration process plugin, configured for lookups in d6_custom_block
-   * and d7_custom_block.
+   * The migration process plugin.
+   *
+   * The plugin is configured for lookups in d6_custom_block and
+   * d7_custom_block.
    *
    * @var \Drupal\migrate\Plugin\MigrateProcessInterface
+   *
+   * @deprecated in drupal:8.8.x and is removed from drupal:9.0.0. Use
+   *   the migrate.lookup service instead.
+   *
+   * @see https://www.drupal.org/node/3047268
    */
   protected $migrationPlugin;
 
+  /**
+   * The migrate lookup service.
+   *
+   * @var \Drupal\migrate\MigrateLookupInterface
+   */
+  protected $migrateLookup;
+
   /**
    * The block_content entity storage handler.
    *
@@ -34,12 +49,32 @@ class BlockPluginId extends ProcessPluginBase implements ContainerFactoryPluginI
   protected $blockContentStorage;
 
   /**
-   * {@inheritdoc}
+   * Constructs a BlockPluginId object.
+   *
+   * @param array $configuration
+   *   The plugin configuration.
+   * @param string $plugin_id
+   *   The plugin ID.
+   * @param mixed $plugin_definition
+   *   The plugin definition.
+   * @param \Drupal\Core\Entity\EntityStorageInterface $storage
+   *   The block content storage object.
+   * @param \Drupal\migrate\MigrateLookupInterface $migrate_lookup
+   *   The migrate lookup service.
    */
-  public function __construct(array $configuration, $plugin_id, array $plugin_definition, EntityStorageInterface $storage, MigrateProcessInterface $migration_plugin) {
+  // @codingStandardsIgnoreLine
+  public function __construct(array $configuration, $plugin_id, array $plugin_definition, EntityStorageInterface $storage, $migrate_lookup) {
     parent::__construct($configuration, $plugin_id, $plugin_definition);
+    if ($migrate_lookup instanceof MigrateProcessInterface) {
+      @trigger_error('Passing a migration process plugin as the fifth argument to ' . __METHOD__ . ' is deprecated in drupal:8.8.0 and will throw an error in drupal:9.0.0. Pass the migrate.lookup service instead. See https://www.drupal.org/node/3047268', E_USER_DEPRECATED);
+      $this->migrationPlugin = $migrate_lookup;
+      $migrate_lookup = \Drupal::service('migrate.lookup');
+    }
+    elseif (!$migrate_lookup instanceof MigrateLookupInterface) {
+      throw new \InvalidArgumentException("The fifth argument to " . __METHOD__ . " must be an instance of MigrateLookupInterface.");
+    }
     $this->blockContentStorage = $storage;
-    $this->migrationPlugin = $migration_plugin;
+    $this->migrateLookup = $migrate_lookup;
   }
 
   /**
@@ -47,18 +82,12 @@ public function __construct(array $configuration, $plugin_id, array $plugin_defi
    */
   public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) {
     $entity_type_manager = $container->get('entity_type.manager');
-    $migration_configuration = [
-      'migration' => [
-        'd6_custom_block',
-        'd7_custom_block',
-      ],
-    ];
     return new static(
       $configuration,
       $plugin_id,
       $plugin_definition,
       $entity_type_manager->getDefinition('block_content') ? $entity_type_manager->getStorage('block_content') : NULL,
-      $container->get('plugin.manager.migrate.process')->createInstance('migration', $migration_configuration, $migration)
+      $container->get('migrate.lookup')
     );
   }
 
@@ -77,17 +106,35 @@ public function transform($value, MigrateExecutableInterface $migrate_executable
             return 'aggregator_feed_block';
           }
           break;
+
         case 'menu':
           return "system_menu_block:$delta";
+
         case 'block':
           if ($this->blockContentStorage) {
-            $block_id = $this->migrationPlugin
-              ->transform($delta, $migrate_executable, $row, $destination_property);
-            if ($block_id) {
+            // This BC layer is included because if the plugin constructor was
+            // called in the legacy way with a migration_lookup process plugin,
+            // it  may have been preconfigured with a different migration to
+            // look up against. While this is unlikely, for maximum BC we will
+            // continue to use the plugin to do the lookup if it is provided,
+            // and support for this will be removed in Drupal 9.
+            if ($this->migrationPlugin) {
+              $block_id = $this->migrationPlugin
+                ->transform($delta, $migrate_executable, $row, $destination_property);
+            }
+            else {
+              $lookup_result = $this->migrateLookup->lookup(['d6_custom_block', 'd7_custom_block'], [$delta]);
+              if ($lookup_result) {
+                $block_id = $lookup_result[0]['id'];
+              }
+            }
+
+            if (!empty($block_id)) {
               return 'block_content:' . $this->blockContentStorage->load($block_id)->uuid();
             }
           }
           break;
+
         default:
           break;
       }
diff --git a/core/modules/block/src/Plugin/migrate/process/BlockVisibility.php b/core/modules/block/src/Plugin/migrate/process/BlockVisibility.php
index 271edd48c3ce04f4e63799124ca27def70ac70f0..fd6773acbab95ba21864218315569e6fd8759ef5 100644
--- a/core/modules/block/src/Plugin/migrate/process/BlockVisibility.php
+++ b/core/modules/block/src/Plugin/migrate/process/BlockVisibility.php
@@ -4,6 +4,7 @@
 
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\migrate\MigrateLookupInterface;
 use Drupal\migrate\Plugin\MigrationInterface;
 use Drupal\migrate\MigrateExecutableInterface;
 use Drupal\migrate\MigrateSkipRowException;
@@ -27,13 +28,27 @@ class BlockVisibility extends ProcessPluginBase implements ContainerFactoryPlugi
   protected $moduleHandler;
 
   /**
-   * The migration process plugin, configured for lookups in the d6_user_role
-   * and d7_user_role migrations.
+   * The migration process plugin.
+   *
+   * The plugin is configured for lookups in the d6_user_role and d7_user_role
+   * migrations.
    *
    * @var \Drupal\migrate\Plugin\MigrateProcessInterface
+   *
+   * @deprecated in drupal:8.8.x and is removed from drupal:9.0.0. Use
+   *   the migrate.lookup service instead.
+   *
+   * @see https://www.drupal.org/node/3047268
    */
   protected $migrationPlugin;
 
+  /**
+   * The migrate lookup service.
+   *
+   * @var \Drupal\migrate\MigrateLookupInterface
+   */
+  protected $migrateLookup;
+
   /**
    * Whether or not to skip blocks that use PHP for visibility. Only applies
    * if the PHP module is not enabled.
@@ -43,12 +58,32 @@ class BlockVisibility extends ProcessPluginBase implements ContainerFactoryPlugi
   protected $skipPHP = FALSE;
 
   /**
-   * {@inheritdoc}
+   * Constructs a BlockVisibility object.
+   *
+   * @param array $configuration
+   *   The plugin configuration.
+   * @param string $plugin_id
+   *   The plugin ID.
+   * @param mixed $plugin_definition
+   *   The plugin definition.
+   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+   *   The module handler service.
+   * @param \Drupal\migrate\MigrateLookupInterface $migrate_lookup
+   *   The migrate lookup service.
    */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, ModuleHandlerInterface $module_handler, MigrateProcessInterface $migration_plugin) {
+  // @codingStandardsIgnoreLine
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, ModuleHandlerInterface $module_handler, $migrate_lookup) {
     parent::__construct($configuration, $plugin_id, $plugin_definition);
+    if ($migrate_lookup instanceof MigrateProcessInterface) {
+      @trigger_error('Passing a migration process plugin as the fifth argument to ' . __METHOD__ . ' is deprecated in drupal:8.8.0 and will throw an error in drupal:9.0.0. Pass the migrate.lookup service instead. See https://www.drupal.org/node/3047268', E_USER_DEPRECATED);
+      $this->migrationPlugin = $migrate_lookup;
+      $migrate_lookup = \Drupal::service('migrate.lookup');
+    }
+    elseif (!$migrate_lookup instanceof MigrateLookupInterface) {
+      throw new \InvalidArgumentException("The fifth argument to " . __METHOD__ . " must be an instance of MigrateLookupInterface.");
+    }
     $this->moduleHandler = $module_handler;
-    $this->migrationPlugin = $migration_plugin;
+    $this->migrateLookup = $migrate_lookup;
 
     if (isset($configuration['skip_php'])) {
       $this->skipPHP = $configuration['skip_php'];
@@ -59,18 +94,12 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition
    * {@inheritdoc}
    */
   public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) {
-    $migration_configuration = [
-      'migration' => [
-        'd6_user_role',
-        'd7_user_role',
-      ],
-    ];
     return new static(
       $configuration,
       $plugin_id,
       $plugin_definition,
       $container->get('module_handler'),
-      $container->get('plugin.manager.migrate.process')->createInstance('migration', $migration_configuration, $migration)
+      $container->get('migrate.lookup')
     );
   }
 
@@ -94,7 +123,22 @@ public function transform($value, MigrateExecutableInterface $migrate_executable
       ];
 
       foreach ($roles as $key => $role_id) {
-        $roles[$key] = $this->migrationPlugin->transform($role_id, $migrate_executable, $row, $destination_property);
+        // This BC layer is included because if the plugin constructor was
+        // called in the legacy way with a migration_lookup process plugin, it
+        // may have been preconfigured with a different migration to look up
+        // against. While this is unlikely, for maximum BC we will continue to
+        // use the plugin to do the lookup if it is provided, and support for
+        // this will be removed in Drupal 9.
+        if ($this->migrationPlugin) {
+          $roles[$key] = $this->migrationPlugin->transform($role_id, $migrate_executable, $row, $destination_property);
+        }
+        else {
+          $lookup_result = $this->migrateLookup->lookup(['d6_user_role', 'd7_user_role'], [$role_id]);
+          if ($lookup_result) {
+            $roles[$key] = $lookup_result[0]['id'];
+          }
+        }
+
       }
       $visibility['user_role']['roles'] = array_combine($roles, $roles);
     }
diff --git a/core/modules/block/tests/src/Unit/Plugin/migrate/process/BlockVisibilityTest.php b/core/modules/block/tests/src/Unit/Plugin/migrate/process/BlockVisibilityTest.php
index 3f7eeca0c2d66a06ca841220cfd11b018f0591ca..d3649b77a7dc145eb05c477855784478013865b3 100644
--- a/core/modules/block/tests/src/Unit/Plugin/migrate/process/BlockVisibilityTest.php
+++ b/core/modules/block/tests/src/Unit/Plugin/migrate/process/BlockVisibilityTest.php
@@ -4,8 +4,8 @@
 
 use Drupal\block\Plugin\migrate\process\BlockVisibility;
 use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\migrate\MigrateLookupInterface;
 use Drupal\migrate\MigrateSkipRowException;
-use Drupal\migrate\Plugin\MigrateProcessInterface;
 use Drupal\Tests\migrate\Unit\process\MigrateProcessTestCase;
 
 /**
@@ -29,8 +29,8 @@ class BlockVisibilityTest extends MigrateProcessTestCase {
   protected function setUp() {
     parent::setUp();
     $this->moduleHandler = $this->prophesize(ModuleHandlerInterface::class);
-    $migration_plugin = $this->prophesize(MigrateProcessInterface::class);
-    $this->plugin = new BlockVisibility([], 'block_visibility_pages', [], $this->moduleHandler->reveal(), $migration_plugin->reveal());
+    $migrate_lookup = $this->prophesize(MigrateLookupInterface::class);
+    $this->plugin = new BlockVisibility([], 'block_visibility_pages', [], $this->moduleHandler->reveal(), $migrate_lookup->reveal());
   }
 
   /**
@@ -86,7 +86,7 @@ public function testTransformPhpDisabled() {
    */
   public function testTransformException() {
     $this->moduleHandler->moduleExists('php')->willReturn(FALSE);
-    $migration_plugin = $this->prophesize(MigrateProcessInterface::class);
+    $migrate_lookup = $this->prophesize(MigrateLookupInterface::class);
     $this->row = $this->getMockBuilder('Drupal\migrate\Row')
       ->disableOriginalConstructor()
       ->setMethods(['getSourceProperty'])
@@ -94,7 +94,7 @@ public function testTransformException() {
     $this->row->expects($this->exactly(2))
       ->method('getSourceProperty')
       ->willReturnMap([['bid', 99], ['module', 'foobar']]);
-    $this->plugin = new BlockVisibility(['skip_php' => TRUE], 'block_visibility_pages', [], $this->moduleHandler->reveal(), $migration_plugin->reveal());
+    $this->plugin = new BlockVisibility(['skip_php' => TRUE], 'block_visibility_pages', [], $this->moduleHandler->reveal(), $migrate_lookup->reveal());
     $this->expectException(MigrateSkipRowException::class);
     $this->expectExceptionMessage("The block with bid '99' from module 'foobar' will have no PHP or request_path visibility configuration.");
     $this->plugin->transform([2, '<?php', []], $this->migrateExecutable, $this->row, 'destinationproperty');
diff --git a/core/modules/block/tests/src/Unit/Plugin/migrate/process/LegacyBlockPluginIdTest.php b/core/modules/block/tests/src/Unit/Plugin/migrate/process/LegacyBlockPluginIdTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..d6d672822d7ec648b84284637250834b9ee35294
--- /dev/null
+++ b/core/modules/block/tests/src/Unit/Plugin/migrate/process/LegacyBlockPluginIdTest.php
@@ -0,0 +1,50 @@
+<?php
+
+namespace Drupal\Tests\block\Unit\Plugin\migrate\process;
+
+use Drupal\block\Plugin\migrate\process\BlockPluginId;
+use Drupal\block_content\Entity\BlockContent;
+use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Drupal\Core\Entity\EntityStorageInterface;
+use Drupal\migrate\MigrateLookupInterface;
+use Drupal\migrate\Plugin\MigrateProcessInterface;
+use Drupal\Tests\migrate\Unit\process\MigrateProcessTestCase;
+
+/**
+ * Tests legacy usage of BlockPluginId.
+ *
+ * @group block
+ * @group legacy
+ *
+ * @coversDefaultClass \Drupal\block\Plugin\migrate\process\BlockPluginId
+ */
+class LegacyBlockPluginIdTest extends MigrateProcessTestCase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp() {
+    parent::setUp();
+    $migrate_lookup = $this->prophesize(MigrateLookupInterface::class);
+    $container = new ContainerBuilder();
+    $container->set('migrate.lookup', $migrate_lookup->reveal());
+    \Drupal::setContainer($container);
+  }
+
+  /**
+   * Tests legacy construction.
+   *
+   * @expectedDeprecation Passing a migration process plugin as the fifth argument to Drupal\block\Plugin\migrate\process\BlockPluginId::__construct is deprecated in drupal:8.8.0 and will throw an error in drupal:9.0.0. Pass the migrate.lookup service instead. See https://www.drupal.org/node/3047268
+   */
+  public function testConstruct() {
+    $process_plugin = $this->prophesize(MigrateProcessInterface::class);
+    $process_plugin->transform(1, $this->migrateExecutable, $this->row, 'destination_property')->willReturn(3);
+    $block = $this->prophesize(BlockContent::class);
+    $block->uuid()->willReturn('123456789');
+    $storage = $this->prophesize(EntityStorageInterface::class);
+    $storage->load(3)->willReturn($block->reveal());
+    $plugin = new BlockPluginId([], '', [], $storage->reveal(), $process_plugin->reveal());
+    $this->assertSame('block_content:123456789', $plugin->transform(['block', 1], $this->migrateExecutable, $this->row, 'destination_property'));
+  }
+
+}
diff --git a/core/modules/block/tests/src/Unit/Plugin/migrate/process/LegacyBlockVisibilityTest.php b/core/modules/block/tests/src/Unit/Plugin/migrate/process/LegacyBlockVisibilityTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..30c7f8b7d62acdd4c79c3e2de0b276d6237c667b
--- /dev/null
+++ b/core/modules/block/tests/src/Unit/Plugin/migrate/process/LegacyBlockVisibilityTest.php
@@ -0,0 +1,135 @@
+<?php
+
+namespace Drupal\Tests\block\Unit\Plugin\migrate\process;
+
+use Drupal\block\Plugin\migrate\process\BlockVisibility;
+use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\migrate\MigrateLookupInterface;
+use Drupal\migrate\MigrateSkipRowException;
+use Drupal\migrate\Plugin\MigrateProcessInterface;
+use Drupal\Tests\migrate\Unit\process\MigrateProcessTestCase;
+
+/**
+ * Tests the block_visibility process plugin.
+ *
+ * @coversDefaultClass \Drupal\block\Plugin\migrate\process\BlockVisibility
+ *
+ * @group block
+ * @group legacy
+ */
+class LegacyBlockVisibilityTest extends MigrateProcessTestCase {
+
+  /**
+   * The module handler.
+   *
+   * @var \Drupal\Core\Extension\ModuleHandlerInterface
+   */
+  protected $moduleHandler;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $migrate_lookup = $this->prophesize(MigrateLookupInterface::class);
+    $container = new ContainerBuilder();
+    $container->set('migrate.lookup', $migrate_lookup->reveal());
+    \Drupal::setContainer($container);
+    $this->moduleHandler = $this->prophesize(ModuleHandlerInterface::class);
+    $migration_plugin = $this->prophesize(MigrateProcessInterface::class);
+    $this->plugin = new BlockVisibility([], 'block_visibility_pages', [], $this->moduleHandler->reveal(), $migration_plugin->reveal());
+  }
+
+  /**
+   * Tests Transform.
+   *
+   * @covers ::transform
+   *
+   * @expectedDeprecation Passing a migration process plugin as the fifth argument to Drupal\block\Plugin\migrate\process\BlockVisibility::__construct is deprecated in drupal:8.8.0 and will throw an error in drupal:9.0.0. Pass the migrate.lookup service instead. See https://www.drupal.org/node/3047268
+   */
+  public function testTransformNoData() {
+    $transformed_value = $this->plugin->transform([0, '', []], $this->migrateExecutable, $this->row, 'destinationproperty');
+    $this->assertEmpty($transformed_value);
+  }
+
+  /**
+   * Tests Transform.
+   *
+   * @covers ::transform
+   *
+   * @expectedDeprecation Passing a migration process plugin as the fifth argument to Drupal\block\Plugin\migrate\process\BlockVisibility::__construct is deprecated in drupal:8.8.0 and will throw an error in drupal:9.0.0. Pass the migrate.lookup service instead. See https://www.drupal.org/node/3047268
+   */
+  public function testTransformSinglePageWithFront() {
+    $visibility = $this->plugin->transform([0, '<front>', []], $this->migrateExecutable, $this->row, 'destinationproperty');
+    $this->assertSame('request_path', $visibility['request_path']['id']);
+    $this->assertTrue($visibility['request_path']['negate']);
+    $this->assertSame('<front>', $visibility['request_path']['pages']);
+  }
+
+  /**
+   * Tests Transform.
+   *
+   * @covers ::transform
+   *
+   * @expectedDeprecation Passing a migration process plugin as the fifth argument to Drupal\block\Plugin\migrate\process\BlockVisibility::__construct is deprecated in drupal:8.8.0 and will throw an error in drupal:9.0.0. Pass the migrate.lookup service instead. See https://www.drupal.org/node/3047268
+   */
+  public function testTransformMultiplePagesWithFront() {
+    $visibility = $this->plugin->transform([1, "foo\n/bar\rbaz\r\n<front>", []], $this->migrateExecutable, $this->row, 'destinationproperty');
+    $this->assertSame('request_path', $visibility['request_path']['id']);
+    $this->assertFalse($visibility['request_path']['negate']);
+    $this->assertSame("/foo\n/bar\n/baz\n<front>", $visibility['request_path']['pages']);
+  }
+
+  /**
+   * Tests Transform.
+   *
+   * @covers ::transform
+   *
+   * @expectedDeprecation Passing a migration process plugin as the fifth argument to Drupal\block\Plugin\migrate\process\BlockVisibility::__construct is deprecated in drupal:8.8.0 and will throw an error in drupal:9.0.0. Pass the migrate.lookup service instead. See https://www.drupal.org/node/3047268
+   */
+  public function testTransformPhpEnabled() {
+    $this->moduleHandler->moduleExists('php')->willReturn(TRUE);
+    $visibility = $this->plugin->transform([2, '<?php', []], $this->migrateExecutable, $this->row, 'destinationproperty');
+    $this->assertSame('php', $visibility['php']['id']);
+    $this->assertFalse($visibility['php']['negate']);
+    $this->assertSame('<?php', $visibility['php']['php']);
+  }
+
+  /**
+   * Tests Transform.
+   *
+   * @covers ::transform
+   *
+   * @expectedDeprecation Passing a migration process plugin as the fifth argument to Drupal\block\Plugin\migrate\process\BlockVisibility::__construct is deprecated in drupal:8.8.0 and will throw an error in drupal:9.0.0. Pass the migrate.lookup service instead. See https://www.drupal.org/node/3047268
+   */
+  public function testTransformPhpDisabled() {
+    $this->moduleHandler->moduleExists('php')->willReturn(FALSE);
+    $transformed_value = $this->plugin->transform([2, '<?php', []], $this->migrateExecutable, $this->row, 'destinationproperty');
+    $this->assertEmpty($transformed_value);
+  }
+
+  /**
+   * Tests Transform.
+   *
+   * @covers ::transform
+   *
+   * @expectedDeprecation Passing a migration process plugin as the fifth argument to Drupal\block\Plugin\migrate\process\BlockVisibility::__construct is deprecated in drupal:8.8.0 and will throw an error in drupal:9.0.0. Pass the migrate.lookup service instead. See https://www.drupal.org/node/3047268
+   */
+  public function testTransformException() {
+    $this->moduleHandler->moduleExists('php')->willReturn(FALSE);
+    $migration_plugin = $this->prophesize(MigrateProcessInterface::class);
+    $this->row = $this->getMockBuilder('Drupal\migrate\Row')
+      ->disableOriginalConstructor()
+      ->setMethods(['getSourceProperty'])
+      ->getMock();
+    $this->row->expects($this->exactly(2))
+      ->method('getSourceProperty')
+      ->willReturnMap([['bid', 99], ['module', 'foobar']]);
+    $this->plugin = new BlockVisibility(['skip_php' => TRUE], 'block_visibility_pages', [], $this->moduleHandler->reveal(), $migration_plugin->reveal());
+    $this->expectException(MigrateSkipRowException::class);
+    $this->expectExceptionMessage("The block with bid '99' from module 'foobar' will have no PHP or request_path visibility configuration.");
+    $this->plugin->transform([2, '<?php', []], $this->migrateExecutable, $this->row, 'destinationproperty');
+  }
+
+}
diff --git a/core/modules/content_translation/migrations/d6_taxonomy_term_localized_translation.yml b/core/modules/content_translation/migrations/d6_taxonomy_term_localized_translation.yml
index 980baf4ae6a994a73a9a2a11c61f4cb48314655c..2521ee9a2aa173070febbc3f4ca1fc3f9f1f23c5 100644
--- a/core/modules/content_translation/migrations/d6_taxonomy_term_localized_translation.yml
+++ b/core/modules/content_translation/migrations/d6_taxonomy_term_localized_translation.yml
@@ -13,7 +13,7 @@ process:
   tid: tid
   langcode: language
   vid:
-    plugin: migration
+    plugin: migration_lookup
     migration: d6_taxonomy_vocabulary
     source: vid
   name:
diff --git a/core/modules/content_translation/migrations/d6_taxonomy_term_translation.yml b/core/modules/content_translation/migrations/d6_taxonomy_term_translation.yml
index 96ccd8d569d9dd90096bfab0d5213298c46786cd..37856b6f06f0e42ec730e44aaf6e1684c90f2008 100644
--- a/core/modules/content_translation/migrations/d6_taxonomy_term_translation.yml
+++ b/core/modules/content_translation/migrations/d6_taxonomy_term_translation.yml
@@ -13,7 +13,7 @@ process:
   tid: tid
   langcode: language
   vid:
-    plugin: migration
+    plugin: migration_lookup
     migration: d6_taxonomy_vocabulary
     source: vid
   name: name
@@ -26,7 +26,7 @@ process:
       method: process
       source: parent
     -
-      plugin: migration
+      plugin: migration_lookup
       migration: d6_taxonomy_term
   parent:
     plugin: default_value
diff --git a/core/modules/content_translation/migrations/d7_taxonomy_term_localized_translation.yml b/core/modules/content_translation/migrations/d7_taxonomy_term_localized_translation.yml
index d0b238567e84752befeac81907b607c521ad03b1..f0b790c9a892c0d65697b5a5863d80c967fae19e 100644
--- a/core/modules/content_translation/migrations/d7_taxonomy_term_localized_translation.yml
+++ b/core/modules/content_translation/migrations/d7_taxonomy_term_localized_translation.yml
@@ -14,7 +14,7 @@ process:
   # Use the language from the locales_target table.
   langcode: ltlanguage
   vid:
-    plugin: migration
+    plugin: migration_lookup
     migration: d7_taxonomy_vocabulary
     source: vid
   name:
diff --git a/core/modules/content_translation/migrations/d7_taxonomy_term_translation.yml b/core/modules/content_translation/migrations/d7_taxonomy_term_translation.yml
index 206df0e46b8047b7787cb111e95ecb8de0d04d04..2a5a0df84658cc066056fadf25ec6e04d2547639 100644
--- a/core/modules/content_translation/migrations/d7_taxonomy_term_translation.yml
+++ b/core/modules/content_translation/migrations/d7_taxonomy_term_translation.yml
@@ -25,7 +25,7 @@ process:
   tid: tid
   langcode: language
   vid:
-    plugin: migration
+    plugin: migration_lookup
     migration: d7_taxonomy_vocabulary
     source: vid
   name: name
@@ -39,7 +39,7 @@ process:
       method: process
       source: parent
     -
-      plugin: migration
+      plugin: migration_lookup
       migration: d7_taxonomy_term
   parent:
     plugin: default_value
diff --git a/core/modules/file/src/Plugin/migrate/process/d6/FieldFile.php b/core/modules/file/src/Plugin/migrate/process/d6/FieldFile.php
index 3b907a3607b07de1cd75f8d447da82c01e0153b0..c5a70930386502a7b5feadb0c38076116698a03a 100644
--- a/core/modules/file/src/Plugin/migrate/process/d6/FieldFile.php
+++ b/core/modules/file/src/Plugin/migrate/process/d6/FieldFile.php
@@ -3,6 +3,7 @@
 namespace Drupal\file\Plugin\migrate\process\d6;
 
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\migrate\MigrateLookupInterface;
 use Drupal\migrate\Plugin\MigrationInterface;
 use Drupal\migrate\MigrateExecutableInterface;
 use Drupal\migrate\Plugin\MigrateProcessInterface;
@@ -21,9 +22,21 @@ class FieldFile extends ProcessPluginBase implements ContainerFactoryPluginInter
    * The migration process plugin, configured for lookups in d6_file.
    *
    * @var \Drupal\migrate\Plugin\MigrateProcessInterface
+   *
+   * @deprecated in drupal:8.8.x and is removed from drupal:9.0.0. Use
+   *   the migrate.lookup service instead.
+   *
+   * @see https://www.drupal.org/node/3047268
    */
   protected $migrationPlugin;
 
+  /**
+   * The migrate lookup service.
+   *
+   * @var \Drupal\migrate\MigrateLookupInterface
+   */
+  protected $migrateLookup;
+
   /**
    * Constructs a FieldFile plugin instance.
    *
@@ -35,32 +48,36 @@ class FieldFile extends ProcessPluginBase implements ContainerFactoryPluginInter
    *   The plugin definition.
    * @param \Drupal\migrate\Plugin\MigrationInterface $migration
    *   The current migration.
-   * @param \Drupal\migrate\Plugin\MigrateProcessInterface $migration_plugin
-   *   An instance of the 'migration' process plugin.
+   * @param \Drupal\migrate\MigrateLookupInterface $migrate_lookup
+   *   The migrate lookup service.
    */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, MigrateProcessInterface $migration_plugin) {
+  // @codingStandardsIgnoreLine
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, $migrate_lookup) {
     parent::__construct($configuration, $plugin_id, $plugin_definition);
+
+    if ($migrate_lookup instanceof MigrateProcessInterface) {
+      @trigger_error('Passing a migration process plugin as the fourth argument to ' . __METHOD__ . ' is deprecated in drupal:8.8.0 and will throw an error in drupal:9.0.0. Pass the migrate.lookup service instead. See https://www.drupal.org/node/3047268', E_USER_DEPRECATED);
+      $this->migrationPlugin = $migrate_lookup;
+      $migrate_lookup = \Drupal::service('migrate.lookup');
+    }
+    elseif (!$migrate_lookup instanceof MigrateLookupInterface) {
+      throw new \InvalidArgumentException("The fifth argument to " . __METHOD__ . " must be an instance of MigrateLookupInterface.");
+    }
     $this->migration = $migration;
-    $this->migrationPlugin = $migration_plugin;
+    $this->migrateLookup = $migrate_lookup;
+
   }
 
   /**
    * {@inheritdoc}
    */
   public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) {
-    // Configure the migration process plugin to look up migrated IDs from
-    // a d6 file migration.
-    $migration_plugin_configuration = $configuration + [
-      'migration' => 'd6_file',
-      'source' => ['fid'],
-    ];
-
     return new static(
       $configuration,
       $plugin_id,
       $plugin_definition,
       $migration,
-      $container->get('plugin.manager.migrate.process')->createInstance('migration', $migration_plugin_configuration, $migration)
+      $container->get('migrate.lookup')
     );
   }
 
@@ -75,7 +92,22 @@ public function transform($value, MigrateExecutableInterface $migrate_executable
     // some reason -- file migration is notoriously brittle -- and we do NOT
     // want to send invalid file references into the field system (it causes
     // fatals), so return an empty item instead.
-    if ($fid = $this->migrationPlugin->transform($value['fid'], $migrate_executable, $row, $destination_property)) {
+    // This BC layer is included because if the plugin constructor was called
+    // in the legacy way with a migration_lookup process plugin, it may have
+    // been preconfigured with a different migration to look up against. While
+    // this is unlikely, for maximum BC we will continue to use the plugin to do
+    // the lookup if it is provided, and support for this will be removed in
+    // Drupal 9.
+    if ($this->migrationPlugin) {
+      $fid = $this->migrationPlugin->transform($value['fid'], $migrate_executable, $row, $destination_property);
+    }
+    else {
+      $lookup_result = $this->migrateLookup->lookup('d6_file', [$value['fid']]);
+      if ($lookup_result) {
+        $fid = $lookup_result[0]['fid'];
+      }
+    }
+    if (!empty($fid)) {
       return [
         'target_id' => $fid,
         'display' => $value['list'],
diff --git a/core/modules/file/tests/src/Kernel/Migrate/process/d6/CckFileTest.php b/core/modules/file/tests/src/Kernel/Migrate/process/d6/CckFileTest.php
index 0ab8ba44fd9bc61e7e920f9e5684fa6576578b84..826cbfc56f6b2868ddc25d8b3d4fcf20af29d6e7 100644
--- a/core/modules/file/tests/src/Kernel/Migrate/process/d6/CckFileTest.php
+++ b/core/modules/file/tests/src/Kernel/Migrate/process/d6/CckFileTest.php
@@ -25,8 +25,7 @@ class CckFileTest extends MigrateDrupalTestBase {
   public function testConfigurableFileMigration() {
     $migration = Migration::create($this->container, [], 'custom_migration', []);
     $cck_file_migration = CckFile::create($this->container, ['migration' => 'custom_file'], 'custom_file', [], $migration);
-    $migration_plugin = $this->readAttribute($cck_file_migration, 'migrationPlugin');
-    $config = $this->readAttribute($migration_plugin, 'configuration');
+    $config = $this->readAttribute($cck_file_migration, 'configuration');
 
     $this->assertEquals($config['migration'], 'custom_file');
   }
diff --git a/core/modules/file/tests/src/Unit/Plugin/migrate/process/d6/CckFileTest.php b/core/modules/file/tests/src/Unit/Plugin/migrate/process/d6/CckFileTest.php
index 8781ef11b470fd449ce7d32f039c1ba0eb9cbb93..e26849a677ec98c624f02ef360115ac1c40ae154 100644
--- a/core/modules/file/tests/src/Unit/Plugin/migrate/process/d6/CckFileTest.php
+++ b/core/modules/file/tests/src/Unit/Plugin/migrate/process/d6/CckFileTest.php
@@ -2,7 +2,9 @@
 
 namespace Drupal\Tests\file\Unit\Plugin\migrate\process\d6;
 
+use Drupal\Core\DependencyInjection\ContainerBuilder;
 use Drupal\file\Plugin\migrate\process\d6\CckFile;
+use Drupal\migrate\MigrateLookupInterface;
 use Drupal\migrate\Plugin\MigrationInterface;
 use Drupal\migrate\MigrateExecutableInterface;
 use Drupal\migrate\Plugin\MigrateProcessInterface;
@@ -21,6 +23,10 @@ class CckFileTest extends UnitTestCase {
    * @expectedDeprecation CckFile is deprecated in Drupal 8.3.x and will be be removed before Drupal 9.0.x. Use \Drupal\file\Plugin\migrate\process\d6\FieldFile instead.
    */
   public function testTransformAltTitle() {
+    $migrate_lookup = $this->prophesize(MigrateLookupInterface::class);
+    $container = new ContainerBuilder();
+    $container->set('migrate.lookup', $migrate_lookup->reveal());
+    \Drupal::setContainer($container);
     $executable = $this->prophesize(MigrateExecutableInterface::class)->reveal();
     $row = $this->prophesize(Row::class)->reveal();
     $migration = $this->prophesize(MigrationInterface::class)->reveal();
diff --git a/core/modules/file/tests/src/Unit/Plugin/migrate/process/d6/FieldFileTest.php b/core/modules/file/tests/src/Unit/Plugin/migrate/process/d6/FieldFileTest.php
index e57821c0a77d01d6d819be96a8d5209e77839ef1..4ee95841b1d13280e349b870f1046d918a713a95 100644
--- a/core/modules/file/tests/src/Unit/Plugin/migrate/process/d6/FieldFileTest.php
+++ b/core/modules/file/tests/src/Unit/Plugin/migrate/process/d6/FieldFileTest.php
@@ -2,7 +2,9 @@
 
 namespace Drupal\Tests\file\Unit\Plugin\migrate\process\d6;
 
+use Drupal\Core\DependencyInjection\ContainerBuilder;
 use Drupal\file\Plugin\migrate\process\d6\FieldFile;
+use Drupal\migrate\MigrateLookupInterface;
 use Drupal\migrate\Plugin\MigrationInterface;
 use Drupal\migrate\MigrateExecutableInterface;
 use Drupal\migrate\Plugin\MigrateProcessInterface;
@@ -22,6 +24,49 @@ public function testTransformAltTitle() {
     $row = $this->prophesize(Row::class)->reveal();
     $migration = $this->prophesize(MigrationInterface::class)->reveal();
 
+    $migrate_lookup = $this->prophesize(MigrateLookupInterface::class);
+    $migrate_lookup->lookup('d6_file', [1])->willReturn([['fid' => 1]]);
+
+    $plugin = new FieldFile([], 'd6_file', [], $migration, $migrate_lookup->reveal());
+
+    $options = [
+      'alt' => 'Foobaz',
+      'title' => 'Wambooli',
+    ];
+    $value = [
+      'fid' => 1,
+      'list' => TRUE,
+      'data' => serialize($options),
+    ];
+
+    $transformed = $plugin->transform($value, $executable, $row, 'foo');
+    $expected = [
+      'target_id' => 1,
+      'display' => TRUE,
+      'description' => '',
+      'alt' => 'Foobaz',
+      'title' => 'Wambooli',
+    ];
+    $this->assertSame($expected, $transformed);
+  }
+
+  /**
+   * Tests that alt and title attributes are included in transformed values.
+   *
+   * @group legacy
+   *
+   * @expectedDeprecation Passing a migration process plugin as the fourth argument to Drupal\file\Plugin\migrate\process\d6\FieldFile::__construct is deprecated in drupal:8.8.0 and will throw an error in drupal:9.0.0. Pass the migrate.lookup service instead. See https://www.drupal.org/node/3047268
+   */
+  public function testLegacyTransformAltTitle() {
+    $migrate_lookup = $this->prophesize(MigrateLookupInterface::class);
+    $container = new ContainerBuilder();
+    $container->set('migrate.lookup', $migrate_lookup->reveal());
+    \Drupal::setContainer($container);
+
+    $executable = $this->prophesize(MigrateExecutableInterface::class)->reveal();
+    $row = $this->prophesize(Row::class)->reveal();
+    $migration = $this->prophesize(MigrationInterface::class)->reveal();
+
     $migration_plugin = $this->prophesize(MigrateProcessInterface::class);
     $migration_plugin->transform(1, $executable, $row, 'foo')->willReturn(1);
 
diff --git a/core/modules/filter/src/Plugin/migrate/process/d6/FilterFormatPermission.php b/core/modules/filter/src/Plugin/migrate/process/d6/FilterFormatPermission.php
index ae8fb9da642db22137335d90046875c69343987d..5d6fcf398cf20f7a2146ac46cd9870afd585a4c3 100644
--- a/core/modules/filter/src/Plugin/migrate/process/d6/FilterFormatPermission.php
+++ b/core/modules/filter/src/Plugin/migrate/process/d6/FilterFormatPermission.php
@@ -3,6 +3,7 @@
 namespace Drupal\filter\Plugin\migrate\process\d6;
 
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\migrate\MigrateLookupInterface;
 use Drupal\migrate\Plugin\MigrationInterface;
 use Drupal\migrate\MigrateExecutableInterface;
 use Drupal\migrate\Plugin\MigrateProcessInterface;
@@ -21,35 +22,64 @@
 class FilterFormatPermission extends ProcessPluginBase implements ContainerFactoryPluginInterface {
 
   /**
-   * The migration plugin.
+   * The Migration process plugin.
    *
    * @var \Drupal\migrate\Plugin\MigrateProcessInterface
+   *
+   * @deprecated in drupal:8.8.x and is removed from drupal:9.0.0. Use
+   *   the migrate.lookup service instead.
+   *
+   * @see https://www.drupal.org/node/3047268
    */
   protected $migrationPlugin;
 
   /**
-   * {@inheritdoc}
+   * The migrate lookup service.
+   *
+   * @var \Drupal\migrate\MigrateLookupInterface
+   */
+  protected $migrateLookup;
+
+  /**
+   * Constructs a FilterFormatPermission plugin instance.
+   *
+   * @param array $configuration
+   *   The plugin configuration.
+   * @param string $plugin_id
+   *   The plugin ID.
+   * @param mixed $plugin_definition
+   *   The plugin definition.
+   * @param \Drupal\migrate\Plugin\MigrationInterface $migration
+   *   The current migration.
+   * @param \Drupal\migrate\MigrateLookupInterface $migrate_lookup
+   *   The migrate lookup service.
    */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, MigrateProcessInterface $migration_plugin) {
+  // @codingStandardsIgnoreLine
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, $migrate_lookup) {
     parent::__construct($configuration, $plugin_id, $plugin_definition);
+    if ($migrate_lookup instanceof MigrateProcessInterface) {
+      @trigger_error('Passing a migration process plugin as the fourth argument to ' . __METHOD__ . ' is deprecated in drupal:8.8.0 and will throw an error in drupal:9.0.0. Pass the migrate.lookup service instead. See https://www.drupal.org/node/3047268', E_USER_DEPRECATED);
+      $this->migrationPlugin = $migrate_lookup;
+      $migrate_lookup = \Drupal::service('migrate.lookup');
+    }
+    elseif (!$migrate_lookup instanceof MigrateLookupInterface) {
+      throw new \InvalidArgumentException("The fifth argument to " . __METHOD__ . " must be an instance of MigrateLookupInterface.");
+    }
     $this->migration = $migration;
-    $this->migrationPlugin = $migration_plugin;
+    $this->migrateLookup = $migrate_lookup;
+
   }
 
   /**
    * {@inheritdoc}
    */
   public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) {
-    $migration_plugin_configuration = $configuration + [
-      'migration' => 'd6_filter_format',
-    ];
-
     return new static(
       $configuration,
       $plugin_id,
       $plugin_definition,
       $migration,
-      $container->get('plugin.manager.migrate.process')->createInstance('migration', $migration_plugin_configuration, $migration)
+      $container->get('migrate.lookup')
     );
   }
 
@@ -60,10 +90,26 @@ public static function create(ContainerInterface $container, array $configuratio
    */
   public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
     $rid = $row->getSourceProperty('rid');
+    $migration = isset($this->configuration['migration']) ? $this->configuration['migration'] : 'd6_filter_format';
     if ($formats = $row->getSourceProperty("filter_permissions:$rid")) {
       foreach ($formats as $format) {
-        $new_id = $this->migrationPlugin->transform($format, $migrate_executable, $row, $destination_property);
-        if ($new_id) {
+
+        // This BC layer is included because if the plugin constructor was
+        // called in the legacy way with a migration_lookup process plugin, it
+        // may have been preconfigured with a different migration to look up
+        // against. While this is unlikely, for maximum BC we will continue to
+        // use the plugin to do the lookup if it is provided, and support for
+        // this will be removed in Drupal 9.
+        if ($this->migrationPlugin) {
+          $new_id = $this->migrationPlugin->transform($format, $migrate_executable, $row, $destination_property);
+        }
+        else {
+          $lookup_result = $this->migrateLookup->lookup($migration, [$format]);
+          if ($lookup_result) {
+            $new_id = $lookup_result[0]['format'];
+          }
+        }
+        if (!empty($new_id)) {
           $value[] = 'use text format ' . $new_id;
         }
       }
diff --git a/core/modules/filter/tests/src/Kernel/Migrate/d6/FilterFormatPermissionTest.php b/core/modules/filter/tests/src/Kernel/Migrate/d6/FilterFormatPermissionTest.php
index 80b0c7d8116b93bae1cda19199dfe355917da9d8..e1fec476cf4e3e201d840e1f6b346276fc3f9811 100644
--- a/core/modules/filter/tests/src/Kernel/Migrate/d6/FilterFormatPermissionTest.php
+++ b/core/modules/filter/tests/src/Kernel/Migrate/d6/FilterFormatPermissionTest.php
@@ -3,7 +3,9 @@
 namespace Drupal\Tests\filter\Kernel\Migrate\d6;
 
 use Drupal\filter\Plugin\migrate\process\d6\FilterFormatPermission;
+use Drupal\migrate\Plugin\MigrateProcessInterface;
 use Drupal\migrate\Plugin\Migration;
+use Drupal\migrate\Plugin\MigrationInterface;
 use Drupal\Tests\migrate_drupal\Kernel\MigrateDrupalTestBase;
 
 /**
@@ -23,10 +25,21 @@ class FilterFormatPermissionTest extends MigrateDrupalTestBase {
   public function testConfigurableFilterFormat() {
     $migration = Migration::create($this->container, [], 'custom_migration', []);
     $filterFormatPermissionMigration = FilterFormatPermission::create($this->container, ['migration' => 'custom_filter_format'], 'custom_filter_format', [], $migration);
-    $migrationPlugin = $this->readAttribute($filterFormatPermissionMigration, 'migrationPlugin');
-    $config = $this->readAttribute($migrationPlugin, 'configuration');
-
+    $config = $this->readAttribute($filterFormatPermissionMigration, 'configuration');
     $this->assertEquals($config['migration'], 'custom_filter_format');
   }
 
+  /**
+   * Tests legacy plugin usage.
+   *
+   * @group legacy
+   *
+   * @expectedDeprecation Passing a migration process plugin as the fourth argument to Drupal\filter\Plugin\migrate\process\d6\FilterFormatPermission::__construct is deprecated in drupal:8.8.0 and will throw an error in drupal:9.0.0. Pass the migrate.lookup service instead. See https://www.drupal.org/node/3047268
+   */
+  public function testLegacyConstruct() {
+    $process_plugin = $this->prophesize(MigrateProcessInterface::class)->reveal();
+    $plugin = new FilterFormatPermission([], '', [], $this->prophesize(MigrationInterface::class)->reveal(), $process_plugin);
+    $this->assertSame($process_plugin, $this->readAttribute($plugin, 'migrationPlugin'));
+  }
+
 }
diff --git a/core/modules/migrate/src/Plugin/migrate/process/MenuLinkParent.php b/core/modules/migrate/src/Plugin/migrate/process/MenuLinkParent.php
index 91014423137585c0243541cae22b41b836ee7394..8e30c85161cfffa3f9da91541200c50e57ead51b 100644
--- a/core/modules/migrate/src/Plugin/migrate/process/MenuLinkParent.php
+++ b/core/modules/migrate/src/Plugin/migrate/process/MenuLinkParent.php
@@ -7,6 +7,7 @@
 use Drupal\Core\Menu\MenuLinkManagerInterface;
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
 use Drupal\Core\Url;
+use Drupal\migrate\MigrateLookupInterface;
 use Drupal\migrate\Plugin\MigrationInterface;
 use Drupal\migrate\MigrateExecutableInterface;
 use Drupal\migrate\MigrateSkipRowException;
@@ -30,21 +31,70 @@ class MenuLinkParent extends ProcessPluginBase implements ContainerFactoryPlugin
   protected $menuLinkManager;
 
   /**
+   * The Migration process plugin.
+   *
    * @var \Drupal\migrate\Plugin\MigrateProcessInterface
+   *
+   * @deprecated in drupal:8.8.x and is removed from drupal:9.0.0. Use
+   *   the migrate.lookup service instead.
+   *
+   * @see https://www.drupal.org/node/3047268
    */
   protected $migrationPlugin;
 
+  /**
+   * The currently running migration.
+   *
+   * @var \Drupal\migrate\Plugin\MigrationInterface
+   */
+  protected $migration;
+
+  /**
+   * The migrate lookup service.
+   *
+   * @var \Drupal\migrate\MigrateLookupInterface
+   */
+  protected $migrateLookup;
+
   /**
    * @var \Drupal\Core\Entity\EntityStorageInterface
    */
   protected $menuLinkStorage;
 
   /**
-   * {@inheritdoc}
+   * Constructs a MenuLinkParent object.
+   *
+   * @param array $configuration
+   *   A configuration array containing information about the plugin instance.
+   * @param string $plugin_id
+   *   The plugin_id for the plugin instance.
+   * @param mixed $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\migrate\MigrateLookupInterface $migrate_lookup
+   *   The migrate lookup service.
+   * @param \Drupal\Core\Menu\MenuLinkManagerInterface $menu_link_manager
+   *   The menu link manager.
+   * @param \Drupal\Core\Entity\EntityStorageInterface $menu_link_storage
+   *   The menu link storage object.
+   * @param \Drupal\migrate\Plugin\MigrationInterface $migration
+   *   The currently running migration.
    */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrateProcessInterface $migration_plugin, MenuLinkManagerInterface $menu_link_manager, EntityStorageInterface $menu_link_storage) {
+  // @codingStandardsIgnoreLine
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, $migrate_lookup, MenuLinkManagerInterface $menu_link_manager, EntityStorageInterface $menu_link_storage, MigrationInterface $migration = NULL) {
     parent::__construct($configuration, $plugin_id, $plugin_definition);
-    $this->migrationPlugin = $migration_plugin;
+    if ($migrate_lookup instanceof MigrateProcessInterface) {
+      @trigger_error('Passing a migration process plugin as the fourth argument to ' . __METHOD__ . ' is deprecated in drupal:8.8.0 and will throw an error in drupal:9.0.0. Pass the migrate.lookup service instead. See https://www.drupal.org/node/3047268', E_USER_DEPRECATED);
+      $this->migrationPlugin = $migrate_lookup;
+      $migrate_lookup = \Drupal::service('migrate.lookup');
+    }
+    elseif (!$migrate_lookup instanceof MigrateLookupInterface) {
+      throw new \InvalidArgumentException("The fourth argument to " . __METHOD__ . " must be an instance of MigrateLookupInterface.");
+    }
+    elseif (!$migration instanceof MigrationInterface) {
+      throw new \InvalidArgumentException("The seventh argument to " . __METHOD__ . " must be an instance of MigrationInterface.");
+    }
+    $this->migration = $migration;
+    $this->migrateLookup = $migrate_lookup;
     $this->menuLinkManager = $menu_link_manager;
     $this->menuLinkStorage = $menu_link_storage;
   }
@@ -58,9 +108,10 @@ public static function create(ContainerInterface $container, array $configuratio
       $configuration,
       $plugin_id,
       $plugin_definition,
-      $container->get('plugin.manager.migrate.process')->createInstance('migration', $migration_configuration, $migration),
+      $container->get('migrate.lookup'),
       $container->get('plugin.manager.menu.link'),
-      $container->get('entity_type.manager')->getStorage('menu_link_content')
+      $container->get('entity_type.manager')->getStorage('menu_link_content'),
+      $migration
     );
   }
 
@@ -75,16 +126,30 @@ public function transform($value, MigrateExecutableInterface $migrate_executable
       // Top level item.
       return '';
     }
-    try {
-      $already_migrated_id = $this
-        ->migrationPlugin
-        ->transform($parent_id, $migrate_executable, $row, $destination_property);
-      if ($already_migrated_id && ($link = $this->menuLinkStorage->load($already_migrated_id))) {
-        return $link->getPluginId();
+    // This BC layer is included because if the plugin constructor was called
+    // in the legacy way with a migration_lookup process plugin, it may have
+    // been preconfigured with a different migration to look up against. While
+    // this is unlikely, for maximum BC we will continue to use the plugin to do
+    // the lookup if it is provided, and support for this will be removed in
+    // Drupal 9.
+    if ($this->migrationPlugin) {
+      try {
+        $already_migrated_id = $this
+          ->migrationPlugin
+          ->transform($parent_id, $migrate_executable, $row, $destination_property);
+      }
+      catch (MigrateSkipRowException $e) {
+      }
+    }
+    else {
+      $lookup_result = $this->migrateLookup->lookup($this->migration->id(), [$parent_id]);
+      if ($lookup_result) {
+        $already_migrated_id = $lookup_result[0]['id'];
       }
     }
-    catch (MigrateSkipRowException $e) {
 
+    if (!empty($already_migrated_id) && ($link = $this->menuLinkStorage->load($already_migrated_id))) {
+      return $link->getPluginId();
     }
 
     if (isset($value[1])) {
diff --git a/core/modules/migrate/tests/src/Unit/process/MenuLinkParentTest.php b/core/modules/migrate/tests/src/Unit/process/MenuLinkParentTest.php
index 238362a0ad45dc1f1efbb9fd735f6810061378b2..d207be0c06e6b6a06c6e15b9e2bcd9f9d16a1925 100644
--- a/core/modules/migrate/tests/src/Unit/process/MenuLinkParentTest.php
+++ b/core/modules/migrate/tests/src/Unit/process/MenuLinkParentTest.php
@@ -3,12 +3,15 @@
 namespace Drupal\Tests\migrate\Unit\process;
 
 use Drupal\Component\Plugin\PluginInspectionInterface;
+use Drupal\Core\DependencyInjection\ContainerBuilder;
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Core\Menu\MenuLinkManagerInterface;
 use Drupal\menu_link_content\MenuLinkContentInterface;
+use Drupal\migrate\MigrateLookupInterface;
 use Drupal\migrate\MigrateSkipRowException;
 use Drupal\migrate\Plugin\migrate\process\MenuLinkParent;
 use Drupal\migrate\Plugin\MigrateProcessInterface;
+use Drupal\migrate\Plugin\MigrationInterface;
 
 /**
  * Tests the menu link parent process plugin.
@@ -18,24 +21,58 @@
  */
 class MenuLinkParentTest extends MigrateProcessTestCase {
 
+  /**
+   * A MigrationInterface prophecy.
+   *
+   * @var \Prophecy\Prophecy\ObjectProphecy
+   */
+  protected $migration;
+
+  /**
+   * A MigrateLookupInterface prophecy.
+   *
+   * @var \Prophecy\Prophecy\ObjectProphecy
+   */
+  protected $migrateLookup;
+
+  /**
+   * A MigrationInterface prophecy.
+   *
+   * @var \Prophecy\Prophecy\ObjectProphecy
+   */
+  protected $menuLinkManager;
+
+  /**
+   * A MigrationInterface prophecy.
+   *
+   * @var \Prophecy\Prophecy\ObjectProphecy
+   */
+  protected $menuLinkStorage;
+
   /**
    * {@inheritdoc}
    */
   protected function setUp() {
     parent::setUp();
-    $migration_plugin = $this->prophesize(MigrateProcessInterface::class);
-    $menu_link_manager = $this->prophesize(MenuLinkManagerInterface::class);
-    $menu_link_storage = $this->prophesize(EntityStorageInterface::class);
-    $this->plugin = new MenuLinkParent([], 'map', [], $migration_plugin->reveal(), $menu_link_manager->reveal(), $menu_link_storage->reveal());
+    $this->migration = $this->prophesize(MigrationInterface::class);
+    $this->migrateLookup = $this->prophesize(MigrateLookupInterface::class);
+    $this->migrateLookup->lookup(NULL, [1])->willReturn([]);
+    $this->menuLinkManager = $this->prophesize(MenuLinkManagerInterface::class);
+    $this->menuLinkStorage = $this->prophesize(EntityStorageInterface::class);
+    $container = new ContainerBuilder();
+    $container->set('migrate.lookup', $this->migrateLookup->reveal());
+    \Drupal::setContainer($container);
+
   }
 
   /**
    * @covers ::transform
    */
   public function testTransformException() {
+    $plugin = new MenuLinkParent([], 'map', [], $this->migrateLookup->reveal(), $this->menuLinkManager->reveal(), $this->menuLinkStorage->reveal(), $this->migration->reveal());
     $this->expectException(MigrateSkipRowException::class);
     $this->expectExceptionMessage("No parent link found for plid '1' in menu 'admin'.");
-    $this->plugin->transform([1, 'admin', NULL], $this->migrateExecutable, $this->row, 'destinationproperty');
+    $plugin->transform([1, 'admin', NULL], $this->migrateExecutable, $this->row, 'destinationproperty');
   }
 
   /**
@@ -44,6 +81,31 @@ public function testTransformException() {
    * @covers ::transform
    */
   public function testTransformExternal() {
+    $menu_link_content = $this->prophesize(MenuLinkContentInterface::class);
+    $menu_link_content->getPluginId()->willReturn('menu_link_content:fe151460-dfa2-4133-8864-c1746f28ab27');
+    $this->menuLinkStorage->loadByProperties([
+      'link__uri' => 'http://example.com',
+    ])->willReturn([
+      9054 => $menu_link_content,
+    ]);
+    $plugin = $this->prophesize(PluginInspectionInterface::class);
+    $this->menuLinkManager->createInstance('menu_link_content:fe151460-dfa2-4133-8864-c1746f28ab27')->willReturn($plugin->reveal());
+    $plugin = new MenuLinkParent([], 'map', [], $this->migrateLookup->reveal(), $this->menuLinkManager->reveal(), $this->menuLinkStorage->reveal(), $this->migration->reveal());
+
+    $result = $plugin->transform([1, 'admin', 'http://example.com'], $this->migrateExecutable, $this->row, 'destinationproperty');
+    $this->assertEquals('menu_link_content:fe151460-dfa2-4133-8864-c1746f28ab27', $result);
+  }
+
+  /**
+   * Tests the plugin when the parent is an external link.
+   *
+   * @covers ::transform
+   *
+   * @group legacy
+   *
+   * @expectedDeprecation Passing a migration process plugin as the fourth argument to Drupal\migrate\Plugin\migrate\process\MenuLinkParent::__construct is deprecated in drupal:8.8.0 and will throw an error in drupal:9.0.0. Pass the migrate.lookup service instead. See https://www.drupal.org/node/3047268
+   */
+  public function testLegacyTransformExternal() {
     $migration_plugin = $this->prophesize(MigrateProcessInterface::class);
     $menu_link_manager = $this->prophesize(MenuLinkManagerInterface::class);
     $menu_link_storage = $this->prophesize(EntityStorageInterface::class);
diff --git a/core/modules/migrate_drupal/tests/src/Kernel/d6/FieldDiscoveryTest.php b/core/modules/migrate_drupal/tests/src/Kernel/d6/FieldDiscoveryTest.php
index cc2fb8c373cd3502c068e07e41441855531af74a..83ae30e9086638c32fc05fac38eb98e0436f9cad 100644
--- a/core/modules/migrate_drupal/tests/src/Kernel/d6/FieldDiscoveryTest.php
+++ b/core/modules/migrate_drupal/tests/src/Kernel/d6/FieldDiscoveryTest.php
@@ -246,7 +246,7 @@ public function testAddFields() {
                 'method' => 'process',
               ],
               2 => [
-                'plugin' => 'migration',
+                'plugin' => 'migration_lookup',
                 'migration' => [
                   0 => 'd6_filter_format',
                   1 => 'd7_filter_format',
diff --git a/core/modules/text/src/Plugin/migrate/field/d6/TextField.php b/core/modules/text/src/Plugin/migrate/field/d6/TextField.php
index dba6398a06448eeb435ea265ef06db88a250e85a..6eeb95f6d0bd380eb27cbb2fca9253a1140c1e47 100644
--- a/core/modules/text/src/Plugin/migrate/field/d6/TextField.php
+++ b/core/modules/text/src/Plugin/migrate/field/d6/TextField.php
@@ -80,7 +80,7 @@ public function defineValueProcessPipeline(MigrationInterface $migration, $field
             'method' => 'process',
           ],
           [
-            'plugin' => 'migration',
+            'plugin' => 'migration_lookup',
             'migration' => [
               'd6_filter_format',
               'd7_filter_format',
diff --git a/core/modules/text/tests/src/Unit/Migrate/d6/TextFieldTest.php b/core/modules/text/tests/src/Unit/Migrate/d6/TextFieldTest.php
index 807b9f16e5ec7d9d1231496f8e2a27f45756b7c4..6e1381e03fe11e584271097b9f3a4403c2d16f8b 100644
--- a/core/modules/text/tests/src/Unit/Migrate/d6/TextFieldTest.php
+++ b/core/modules/text/tests/src/Unit/Migrate/d6/TextFieldTest.php
@@ -66,7 +66,7 @@ public function testProcessFilteredTextFieldValues() {
     // Ensure that filter format IDs will be looked up in the filter format
     // migrations.
     $lookup = $process['process']['format'][2];
-    $this->assertSame('migration', $lookup['plugin']);
+    $this->assertSame('migration_lookup', $lookup['plugin']);
     $this->assertContains('d6_filter_format', $lookup['migration']);
     $this->assertContains('d7_filter_format', $lookup['migration']);
     $this->assertSame('format', $lookup['source']);
@@ -89,7 +89,7 @@ public function testFilteredTextValueProcessPipeline() {
     // Ensure that filter format IDs will be looked up in the filter format
     // migrations.
     $lookup = $process['process']['format'][2];
-    $this->assertSame('migration', $lookup['plugin']);
+    $this->assertSame('migration_lookup', $lookup['plugin']);
     $this->assertContains('d6_filter_format', $lookup['migration']);
     $this->assertContains('d7_filter_format', $lookup['migration']);
     $this->assertSame('format', $lookup['source']);
diff --git a/core/modules/text/tests/src/Unit/Plugin/migrate/field/d6/TextFieldTest.php b/core/modules/text/tests/src/Unit/Plugin/migrate/field/d6/TextFieldTest.php
index c6970f4d9502c9e4cd9a858e3d25d798fc77fb99..5f8dc9c66acfb2d20013e38316fe52c6d103abfd 100644
--- a/core/modules/text/tests/src/Unit/Plugin/migrate/field/d6/TextFieldTest.php
+++ b/core/modules/text/tests/src/Unit/Plugin/migrate/field/d6/TextFieldTest.php
@@ -61,7 +61,7 @@ public function testProcessFilteredTextFieldValues($method = 'defineValueProcess
     // Ensure that filter format IDs will be looked up in the filter format
     // migrations.
     $lookup = $process['process']['format'][2];
-    $this->assertSame('migration', $lookup['plugin']);
+    $this->assertSame('migration_lookup', $lookup['plugin']);
     $this->assertContains('d6_filter_format', $lookup['migration']);
     $this->assertContains('d7_filter_format', $lookup['migration']);
     $this->assertSame('format', $lookup['source']);
diff --git a/core/tests/Drupal/Tests/Listeners/DeprecationListenerTrait.php b/core/tests/Drupal/Tests/Listeners/DeprecationListenerTrait.php
index 95f4984c4aa03bc29b8910117b9ad2a7c6535afd..b669a36258e1c068878d349c6dc644423701e5bf 100644
--- a/core/tests/Drupal/Tests/Listeners/DeprecationListenerTrait.php
+++ b/core/tests/Drupal/Tests/Listeners/DeprecationListenerTrait.php
@@ -144,7 +144,6 @@ public static function getSkippedDeprecations() {
       'MigrateCckFieldPluginManager is deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.x. Use \Drupal\migrate_drupal\Annotation\MigrateFieldPluginManager instead.',
       'MigrateCckFieldPluginManagerInterface is deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.x. Use \Drupal\migrate_drupal\Annotation\MigrateFieldPluginManagerInterface instead.',
       'The "plugin.manager.migrate.cckfield" service is deprecated. You should use the \'plugin.manager.migrate.field\' service instead. See https://www.drupal.org/node/2751897',
-      'The Drupal\migrate\Plugin\migrate\process\Migration is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use Drupal\migrate\Plugin\migrate\process\MigrationLookup',
       'Passing in arguments the legacy way is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Provide the right parameter names in the method, similar to controllers. See https://www.drupal.org/node/2894819',
       'The "serializer.normalizer.file_entity.hal" normalizer service is deprecated: it is obsolete, it only remains available for backwards compatibility.',
       'The Symfony\Component\ClassLoader\ApcClassLoader class is deprecated since Symfony 3.3 and will be removed in 4.0. Use `composer install --apcu-autoloader` instead.',