diff --git a/core/modules/migrate/src/Plugin/migrate/process/FileCopy.php b/core/modules/migrate/src/Plugin/migrate/process/FileCopy.php
index 4759146..53d0e73 100644
--- a/core/modules/migrate/src/Plugin/migrate/process/FileCopy.php
+++ b/core/modules/migrate/src/Plugin/migrate/process/FileCopy.php
@@ -53,6 +53,7 @@ public function __construct(array $configuration, $plugin_id, array $plugin_defi
     $configuration += array(
       'move' => FALSE,
       'rename' => FALSE,
+      'reuse' => FALSE,
     );
     parent::__construct($configuration, $plugin_id, $plugin_definition);
     $this->streamWrapperManager = $stream_wrappers;
@@ -130,8 +131,13 @@ protected function writeFile($source, $destination, $replace = FILE_EXISTS_REPLA
     if ($this->configuration['move']) {
       return file_unmanaged_move($source, $destination, $replace);
     }
+    // Check if there is a destination available for copying. If there isn't,
+    // it already exists at the destination and the replace flag tells us to not
+    // replace it. In that case, return the original destination.
+    if (!($final_destination = file_destination($destination, $replace))) {
+      return $destination;
+    }
     // We can't use file_unmanaged_copy because it will break with remote Urls.
-    $final_destination = file_destination($destination, $replace);
     if (@copy($source, $final_destination)) {
       return $final_destination;
     }
@@ -142,13 +148,17 @@ protected function writeFile($source, $destination, $replace = FILE_EXISTS_REPLA
    * Determines how to handle file conflicts.
    *
    * @return int
-   *   Either FILE_EXISTS_REPLACE (default) or FILE_EXISTS_RENAME, depending
-   *   on the current configuration.
+   *   FILE_EXISTS_REPLACE (default) FILE_EXISTS_RENAME, or FILE_EXISTS_ERROR
+   *   depending on the current configuration.
    */
   protected function getOverwriteMode() {
     if (!empty($this->configuration['rename'])) {
       return FILE_EXISTS_RENAME;
     }
+    if (!empty($this->configuration['reuse'])) {
+      return FILE_EXISTS_ERROR;
+    }
+
     return FILE_EXISTS_REPLACE;
   }
 
diff --git a/core/modules/migrate/tests/src/Kernel/process/CopyFileTest.php b/core/modules/migrate/tests/src/Kernel/process/CopyFileTest.php
index 288ebfb..375d64c 100644
--- a/core/modules/migrate/tests/src/Kernel/process/CopyFileTest.php
+++ b/core/modules/migrate/tests/src/Kernel/process/CopyFileTest.php
@@ -36,6 +36,12 @@ protected function setUp() {
     $this->container->get('stream_wrapper_manager')->registerWrapper('temporary', 'Drupal\Core\StreamWrapper\TemporaryStream', StreamWrapperInterface::LOCAL_NORMAL);
   }
 
+  protected function tearDown() {
+    parent::tearDown();
+    
+    unlink('public://file1.jpg');
+  }
+
   /**
    * Test successful imports/copies.
    */
@@ -71,6 +77,22 @@ public function testSuccessfulCopies() {
   }
 
   /**
+   * Test successful file reuse.
+   */
+  public function testSuccessfulReuse() {
+    $source_path = $this->root . '/core/modules/simpletest/files/image-test.jpg';
+    $destination_path = 'public://file1.jpg';
+    $file_reuse = file_unmanaged_copy($source_path, $destination_path);
+    $timestamp = (new \SplFileInfo($file_reuse))->getMTime();
+    $configuration = ['reuse' => TRUE];
+    $this->doImport($source_path, $destination_path, $configuration);
+    self::assertEquals((new \SplFileInfo($file_reuse))->getMTime(), $timestamp);
+    $configuration = ['reuse' => FALSE];
+    $this->doImport($source_path, $destination_path, $configuration);
+    self::assertNotEquals((new \SplFileInfo($file_reuse))->getMTime(), $timestamp);
+  }
+
+  /**
    * Test successful moves.
    */
   public function testSuccessfulMoves() {
