diff --git a/core/modules/filter/migration_templates/d7_filter_format.yml b/core/modules/filter/migration_templates/d7_filter_format.yml
new file mode 100755
index 0000000..474b0d4
--- /dev/null
+++ b/core/modules/filter/migration_templates/d7_filter_format.yml
@@ -0,0 +1,21 @@
+id: d7_filter_format
+label: Drupal 7 filter format configuration
+migration_tags:
+  - Drupal 7
+source:
+  plugin: d7_filter_format
+process:
+  format:
+    -
+      plugin: machine_name
+      source: name
+    -
+      plugin: dedupe_entity
+      entity_type: filter_format
+      field: format
+      length: 32
+  name: name
+  cache: cache
+  filters: filters
+destination:
+  plugin: entity:filter_format
diff --git a/core/modules/filter/src/Plugin/migrate/source/d7/FilterFormat.php b/core/modules/filter/src/Plugin/migrate/source/d7/FilterFormat.php
new file mode 100755
index 0000000..88475f5
--- /dev/null
+++ b/core/modules/filter/src/Plugin/migrate/source/d7/FilterFormat.php
@@ -0,0 +1,89 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\filter\Plugin\migrate\source\d7\FilterFormat.
+ */
+
+namespace Drupal\filter\Plugin\migrate\source\d7;
+
+use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
+use Drupal\migrate\Row;
+
+
+/**
+ * Drupal 7 role source from database.
+ *
+ * @MigrateSource(
+ *   id = "d7_filter_format"
+ * )
+ */
+class FilterFormat extends DrupalSqlBase {
+
+  /**
+   * The format current.
+   *
+   * @var int
+   */
+  protected $format_current;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function query() {
+     return $this->select('filter_format', 'f')
+      ->fields('f')
+      // Ignore the plain text format.
+      ->condition('format', 'plain_text', '<>');
+   }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fields() {
+    return array(
+      'format' => $this->t('Format ID.'),
+      'name' => $this->t('The name of the filter format.'),
+      'cache' => $this->t('Flag to indicate whether format is cachable. (1 = cachable, 0 = not cachable).'),
+      'status'=>$this->t('The status of the filter format'),
+      'weight'=>$this->t('The weight of the filter format'),
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function prepareRow(Row $row) {
+    // Find filters for this format.
+    $filters = $this->select('filter', 'f')
+      ->fields('f')
+      ->condition('format', $row->getSourceProperty('format'))
+      ->condition('name', [
+        'filter_html',
+        'filter_autop',
+        'filter_url',
+        'filter_htmlcorrector',
+        'filter_html_escape',
+        'php_code',
+      ], 'IN')
+      ->condition('status', 1)
+      ->execute()
+      ->fetchAllAssoc('name');
+
+    foreach ($filters as &$filter) {
+      $filter['settings'] = unserialize($filter['settings']);
+    }
+    $row->setSourceProperty('filters', $filters);
+
+    return parent::prepareRow($row);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getIds() {
+    $ids['format']['type'] = 'string';
+    return $ids;
+  }
+
+}
diff --git a/core/modules/filter/src/Tests/Migrate/d7/MigrateFilterFormatTest.php b/core/modules/filter/src/Tests/Migrate/d7/MigrateFilterFormatTest.php
new file mode 100644
index 0000000..7a12b4e
--- /dev/null
+++ b/core/modules/filter/src/Tests/Migrate/d7/MigrateFilterFormatTest.php
@@ -0,0 +1,66 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\filter\Tests\Migrate\d7\MigrateFilterFormatTest.
+ */
+
+namespace Drupal\filter\Tests\Migrate\d7;
+
+use Drupal\filter\Entity\FilterFormat;
+use Drupal\filter\FilterFormatInterface;
+use Drupal\migrate_drupal\Tests\d7\MigrateDrupal7TestBase;
+
+/**
+ * Upgrade variables to filter.formats.*.yml.
+ *
+ * @group filter
+ */
+class MigrateFilterFormatTest extends MigrateDrupal7TestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  static $modules = array('filter');
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->loadDumps(['Filter.php', 'FilterFormat.php', 'Variable.php']);
+    $this->executeMigration('d7_filter_format');
+  }
+
+  /**
+   * Asserts various aspects of a filter format entity.
+   *
+   * @param string $id
+   *   The format ID.
+   * @param string $label
+   *   The expected label of the format.
+   * @param array $enabled_filters
+   *   The expected filters in the format, keyed by ID.
+   */
+  protected function assertEntity($id, $label, array $enabled_filters) {
+    /** @var \Drupal\filter\FilterFormatInterface $entity */
+    $entity = FilterFormat::load($id);
+    $this->assertTrue($entity instanceof FilterFormatInterface);
+    $this->assertIdentical($label, $entity->label());
+    // get('filters') will return enabled filters only, not all of them.
+    $this->assertIdentical($enabled_filters, array_keys($entity->get('filters')));
+  }
+
+  /**
+   * Tests the Drupal 7 filter format to Drupal 8 migration.
+   */
+  public function testFilterFormat() {
+    $this->assertEntity('custom_text_format', 'Custom Text format', ['filter_autop', 'filter_html']);
+    $this->assertEntity('filtered_html', 'Filtered HTML', ['filter_autop', 'filter_html', 'filter_htmlcorrector', 'filter_url']);
+    $this->assertEntity('full_html', 'Full HTML', ['filter_autop', 'filter_htmlcorrector', 'filter_url']);
+
+    // The plain text format is skipped by the source plugin.
+    $this->assertNull(FilterFormat::load('drupal_7_plain_text'));
+  }
+
+}
diff --git a/core/modules/filter/tests/src/Unit/Plugin/migrate/source/d6/FilterFormatTest.php b/core/modules/filter/tests/src/Unit/Plugin/migrate/source/d6/FilterFormatTest.php
index ebdb776..9d27e4e 100644
--- a/core/modules/filter/tests/src/Unit/Plugin/migrate/source/d6/FilterFormatTest.php
+++ b/core/modules/filter/tests/src/Unit/Plugin/migrate/source/d6/FilterFormatTest.php
@@ -10,17 +10,14 @@
 use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
 
 /**
- * Tests D6 filter_formats table source plugin.
+ * Tests d6_filter_format source plugin.
  *
  * @group filter
  */
 class FilterFormatTest extends MigrateSqlSourceTestCase {
 
-  // The plugin system is not working during unit testing so the source plugin
-  // class needs to be manually specified.
   const PLUGIN_CLASS = 'Drupal\filter\Plugin\migrate\source\d6\FilterFormat';
 
-  // The fake Migration configuration entity.
   protected $migrationConfiguration = array(
     'id' => 'test',
     'highWaterProperty' => array('field' => 'test'),
diff --git a/core/modules/filter/tests/src/Unit/Plugin/migrate/source/d7/FilterFormatTest.php b/core/modules/filter/tests/src/Unit/Plugin/migrate/source/d7/FilterFormatTest.php
new file mode 100644
index 0000000..06d8d6b
--- /dev/null
+++ b/core/modules/filter/tests/src/Unit/Plugin/migrate/source/d7/FilterFormatTest.php
@@ -0,0 +1,86 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\filter\Unit\Plugin\migrate\source\d7\FilterFormatTest.
+ */
+
+namespace Drupal\Tests\filter\Unit\Plugin\migrate\source\d7;
+
+use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
+
+/**
+ * Tests d7_filter_format source plugin.
+ *
+ * @group filter
+ */
+class FilterFormatTest extends MigrateSqlSourceTestCase {
+
+  const PLUGIN_CLASS = 'Drupal\filter\Plugin\migrate\source\d7\FilterFormat';
+
+  protected $migrationConfiguration = array(
+    'id' => 'test',
+    'source' => array(
+      'plugin' => 'd6_filter_formats',
+    ),
+  );
+
+  protected $expectedResults = array(
+    array(
+      'format' => 'custom_text_format',
+      'name' => 'Custom Text format',
+      'cache' => 1,
+      'status' => 1,
+      'weight' => 0,
+      'filters' => array(
+        'filter_autop' => array(
+          'module' => 'filter',
+          'name' => 'filter_autop',
+          'weight' => 0,
+          'status' => 1,
+          'settings' => array(),
+        ),
+        'filter_html' => array(
+          'module' => 'filter',
+          'name' => 'filter_html',
+          'weight' => 1,
+          'status' => 1,
+          'settings' => array(),
+        ),
+      ),
+    ),
+    array(
+      'format' => 'full_html',
+      'name' => 'Full HTML',
+      'cache' => 1,
+      'status' => 1,
+      'weight' => 1,
+      'filters' => array(
+        'filter_url' => array(
+          'module' => 'filter',
+          'name' => 'filter_url',
+          'weight' => 0,
+          'status' => 1,
+          'settings' => array(),
+        ),
+      ),
+    ),
+  );
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    foreach ($this->expectedResults as $row) {
+      foreach ($row['filters'] as $filter) {
+        $filter['format'] = $row['format'];
+        $filter['settings'] = serialize($filter['settings']);
+        $this->databaseContents['filter'][] = $filter;
+      }
+      unset($row['filters']);
+      $this->databaseContents['filter_format'][] = $row;
+    }
+    parent::setUp();
+  }
+
+}
