diff --git a/core/modules/migrate/src/Plugin/migrate/destination/EntityFile.php b/core/modules/migrate/src/Plugin/migrate/destination/EntityFile.php
index b338fba64f8bd073731acafb0d4af02fa2a28430..77b471f115d06974cb5e2dd9267d453b6ee19378 100644
--- a/core/modules/migrate/src/Plugin/migrate/destination/EntityFile.php
+++ b/core/modules/migrate/src/Plugin/migrate/destination/EntityFile.php
@@ -50,6 +50,11 @@ public function import(Row $row, array $old_destination_id_values = array()) {
     // already absolute.
     $source = $this->isTempFile($destination) ? $file : $this->configuration['source_base_path'] . $file;
 
+    $dirname = drupal_dirname($destination);
+    if (!file_prepare_directory($dirname, FILE_CREATE_DIRECTORY)) {
+      throw new MigrateException(t('Could not create directory %dirname', array('%dirname' => $dirname)));
+    }
+
     // If the start and end file is exactly the same, there is nothing to do.
     if (drupal_realpath($source) === drupal_realpath($destination)) {
       return parent::import($row, $old_destination_id_values);
@@ -62,11 +67,7 @@ public function import(Row $row, array $old_destination_id_values = array()) {
         $replace = FILE_EXISTS_RENAME;
       }
     }
-    $dirname = drupal_dirname($destination);
-    if (!file_prepare_directory($dirname, FILE_CREATE_DIRECTORY)) {
-      throw new MigrateException(t('Could not create directory %dirname',
-        array('%dirname' => $dirname)));
-    }
+
     if ($this->configuration['move']) {
       $copied = file_unmanaged_move($source, $destination, $replace);
     }
@@ -78,7 +79,7 @@ public function import(Row $row, array $old_destination_id_values = array()) {
         throw new MigrateException(t('File %file could not be copied because a file by that name already exists in the destination directory (%destination)', array('%file' => $source, '%destination' => $original_destination)));
       }
       $source = $this->urlencode($source);
-      $copied = copy($source, $destination);
+      $copied = @copy($source, $destination);
     }
     if ($copied) {
       return parent::import($row, $old_destination_id_values);
diff --git a/core/modules/migrate/tests/src/Unit/destination/EntityFileTest.php b/core/modules/migrate/tests/src/Unit/destination/EntityFileTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..731c722da0759a45c1fc1fa88316c77a34b46428
--- /dev/null
+++ b/core/modules/migrate/tests/src/Unit/destination/EntityFileTest.php
@@ -0,0 +1,160 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\migrate\Unit\destination\EntityFileTest.
+ */
+
+namespace Drupal\Tests\migrate\Unit\destination;
+
+use Drupal\migrate\Row;
+use Drupal\migrate\Plugin\migrate\destination\EntityFile;
+use Drupal\simpletest\KernelTestBase;
+use Drupal\Core\Entity\ContentEntityInterface;
+use Drupal\entity_test\Entity\EntityTest;
+use Drupal\migrate\MigrateException;
+
+/**
+ * Tests the entity file destination plugin.
+ *
+ * @group migrate
+ */
+class EntityFileTest extends KernelTestBase {
+
+  /**
+   * Modules to install.
+   *
+   * @var array
+   */
+  public static $modules = array('system', 'entity_test', 'user');
+
+  /**
+   * @var \Drupal\Tests\migrate\Unit\destination\TestEntityFile $destination
+   */
+  protected $destination;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp() {
+    parent::setUp();
+    $this->destination = new TestEntityFile([]);
+
+    $this->installConfig(['system']);
+    file_put_contents('/tmp/test-file.jpg', '');
+  }
+
+  /**
+   * Test successful imports/copies.
+   */
+  public function testSuccessfulCopies() {
+    foreach ($this->localFileDataProvider() as $data) {
+      list($row_values, $destination_path, $expected, $source_base_path) = $data;
+
+      $this->doImport($row_values, $destination_path, $source_base_path);
+      $message = $expected ? sprintf('File %s exists', $destination_path) : sprintf('File %s does not exist', $destination_path);
+      $this->assertIdentical($expected, is_file($destination_path), $message);
+    }
+  }
+
+  /**
+   * The data provider for testing the file destination.
+   *
+   * @return array
+   *   An array of file permutations to test.
+   */
+  protected function localFileDataProvider() {
+    global $base_url;
+    return [
+      // Test a local to local copy.
+      [['filepath' => 'core/modules/simpletest/files/image-test.jpg'], 'public://file1.jpg', TRUE, DRUPAL_ROOT . '/'],
+      // Test a temporary file using an absolute path.
+      [['filepath' => '/tmp/test-file.jpg'], 'temporary://test.jpg', TRUE, ''],
+      // Test a remote path to local.
+      [['filepath' => 'core/modules/simpletest/files/image-test.jpg'], 'public://remote-file.jpg', TRUE, $base_url . '/'],
+      // Test a remote path to local inside a folder that doesn't exist.
+      [['filepath' => 'core/modules/simpletest/files/image-test.jpg'], 'public://folder/remote-file.jpg', TRUE, DRUPAL_ROOT . '/'],
+    ];
+  }
+
+
+  /**
+   * Test that non-existent files throw an exception.
+   */
+  public function testNonExistentSourceFile() {
+    try {
+      $this->doImport(['filepath' => '/none/existent/file'], 'public://wontmatter.jpg');
+    }
+    catch (MigrateException $e) {}
+    $destination = '/none/existent/file';
+    $this->assertIdentical($e->getMessage(), 'File <em class="placeholder">' . $destination . '</em> could not be copied to <em class="placeholder">public://wontmatter.jpg</em>.');
+  }
+
+  /**
+   * Do an import using the destination.
+   *
+   * @param array $row_values
+   *   An array of row values.
+   * @param string $destination_path
+   *   The destination path to copy to.
+   * @param string $source_base_path
+   *   The source base path.
+   * @return array
+   *   An array of saved entities ids.
+   *
+   * @throws \Drupal\migrate\MigrateException
+   */
+  protected function doImport($row_values, $destination_path, $source_base_path = '') {
+    $row = new Row($row_values, []);
+    $row->setDestinationProperty('uri', $destination_path);
+    $this->destination->configuration['source_base_path'] = $source_base_path;
+
+    // Importing asserts there are no errors, then we just check the file has
+    // been copied into place.
+    return $this->destination->import($row, array());
+  }
+
+}
+
+class TestEntityFile extends EntityFile {
+
+  /**
+   * This is needed to be passed to $this->save().
+   *
+   * @var \Drupal\Core\Entity\ContentEntityInterface
+   */
+  public $mockEntity;
+
+  /**
+   * Make this public for easy writing during tests.
+   *
+   * @var array
+   */
+  public $configuration;
+
+  public function __construct($configuration) {
+    $configuration +=  array(
+      'source_base_path' => '',
+      'source_path_property' => 'filepath',
+      'destination_path_property' => 'uri',
+      'move' => FALSE,
+      'urlencode' => FALSE,
+    );
+    $this->configuration = $configuration;
+    // We need a mock entity to be passed to save to prevent strict exceptions.
+    $this->mockEntity = EntityTest::create();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getEntity(Row $row, array $old_destination_id_values) {
+    return $this->mockEntity;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function save(ContentEntityInterface $entity, array $old_destination_id_values = array()) {}
+
+}