diff --git a/migrations/d7_flag.yml b/migrations/d7_flag.yml
new file mode 100644
index 0000000..a31b23e
--- /dev/null
+++ b/migrations/d7_flag.yml
@@ -0,0 +1,33 @@
+id: d7_flag
+label: Flag configuration
+migration_tags:
+  - Drupal 7
+source:
+  plugin: d7_flag
+process:
+  id: name
+  label: title
+  bundles: bundles
+  entity_type: entity_type
+  global: global
+  weight: 'options/weight'
+  flag_short: 'options/flag_short'
+  flag_long: 'options/flag_long'
+  flag_message: 'options/flag_message'
+  unflag_short: 'options/unflag_short'
+  unflag_long: 'options/unflag_long'
+  unflag_message: 'options/unflag_message'
+  unflag_denied_text: 'options/unflag_denied_text'
+  flag_type: flag_type
+  link_type:
+    plugin: static_map
+    source: 'options/link_type'
+    map:
+      toggle: ajax_link
+      normal: reload
+      confirm: confirm
+      form: field_entry
+  flagTypeConfig: flagTypeConfig
+  linkTypeConfig: linkTypeConfig
+destination:
+  plugin: entity:flag
diff --git a/migrations/d7_flag_counts.yml b/migrations/d7_flag_counts.yml
new file mode 100644
index 0000000..665eac5
--- /dev/null
+++ b/migrations/d7_flag_counts.yml
@@ -0,0 +1,17 @@
+id: d7_flag_counts
+label: Flag counts
+migration_tags:
+  - Drupal 7
+source:
+  plugin: d7_flag_counts
+process:
+  flag_id: flag_name
+  entity_type: entity_type
+  entity_id: entity_id
+  count: count
+  last_updated: last_updated
+destination:
+  plugin: flag_counts
+migration_dependencies:
+  required:
+    - d7_flag
\ No newline at end of file
diff --git a/migrations/d7_flagging.yml b/migrations/d7_flagging.yml
new file mode 100644
index 0000000..6e832ca
--- /dev/null
+++ b/migrations/d7_flagging.yml
@@ -0,0 +1,20 @@
+id: d7_flagging
+label: Flagging
+migration_tags:
+  - Drupal 7
+source:
+  plugin: d7_flagging
+process:
+  id: flagging_id
+  flag_id: flag_name
+  entity_type: entity_type
+  entity_id: entity_id
+  global: global
+  uid: uid
+  created: timestamp
+destination:
+  plugin: entity:flagging
+migration_dependencies:
+  required:
+    - d7_flag
+    - d7_flag_counts
\ No newline at end of file
diff --git a/src/Plugin/migrate/destination/EntityFlag.php b/src/Plugin/migrate/destination/EntityFlag.php
new file mode 100644
index 0000000..f608d9c
--- /dev/null
+++ b/src/Plugin/migrate/destination/EntityFlag.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace Drupal\flag\Plugin\migrate\destination;
+
+use Drupal\migrate\Plugin\migrate\destination\EntityConfigBase;
+use Drupal\migrate\Row;
+
+/**
+ * @MigrateDestination(
+ *   id = "entity:flag"
+ * )
+ */
+class EntityFlag extends EntityConfigBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function import(Row $row, array $old_destination_id_values = array()) {
+    $entity_ids = parent::import($row, $old_destination_id_values);
+    return $entity_ids;
+  }
+
+}
diff --git a/src/Plugin/migrate/destination/EntityFlagging.php b/src/Plugin/migrate/destination/EntityFlagging.php
new file mode 100644
index 0000000..8163e99
--- /dev/null
+++ b/src/Plugin/migrate/destination/EntityFlagging.php
@@ -0,0 +1,93 @@
+<?php
+
+namespace Drupal\flag\Plugin\migrate\destination;
+
+use Drupal\Core\Entity\EntityManagerInterface;
+use Drupal\Core\Entity\EntityStorageInterface;
+use Drupal\Core\Entity\Query\QueryFactory;
+use Drupal\Core\Field\FieldTypePluginManagerInterface;
+use Drupal\Core\State\StateInterface;
+use Drupal\migrate\Plugin\MigrationInterface;
+use Drupal\migrate\Plugin\migrate\destination\EntityContentBase;
+use Drupal\migrate\Row;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * @MigrateDestination(
+ *   id = "entity:flagging"
+ * )
+ */
+class EntityFlagging extends EntityContentBase {
+
+  /**
+   * The state storage object.
+   *
+   * @var \Drupal\Core\State\StateInterface
+   */
+  protected $state;
+
+  /**
+   * The entity query object.
+   *
+   * @var \Drupal\Core\Entity\Query\QueryInterface
+   */
+  protected $entityQuery;
+
+  /**
+   * Builds a flagging entity destination.
+   *
+   * @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 MigrationInterface $migration
+   *   The migration.
+   * @param EntityStorageInterface $storage
+   *   The storage for this entity type.
+   * @param array $bundles
+   *   The list of bundles this entity type has.
+   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
+   *   The entity manager service.
+   * @param \Drupal\Core\Field\FieldTypePluginManagerInterface $field_type_manager
+   *   The field type plugin manager service.
+   * @param \Drupal\Core\State\StateInterface $state
+   *   The state storage object.
+   * @param \Drupal\Core\Entity\Query\QueryFactory $entity_query
+   *   The query object that can query the given entity type.
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles, EntityManagerInterface $entity_manager, FieldTypePluginManagerInterface $field_type_manager, StateInterface $state, QueryFactory $entity_query) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $storage, $bundles, $entity_manager, $field_type_manager);
+    $this->state = $state;
+    $this->entityQuery = $entity_query;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) {
+    $entity_type = static::getEntityTypeId($plugin_id);
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $migration,
+      $container->get('entity.manager')->getStorage($entity_type),
+      array_keys($container->get('entity.manager')->getBundleInfo($entity_type)),
+      $container->get('entity.manager'),
+      $container->get('plugin.manager.field.field_type'),
+      $container->get('state'),
+      $container->get('entity.query')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function import(Row $row, array $old_destination_id_values = array()) {
+    $entity_ids = parent::import($row, $old_destination_id_values);
+    return $entity_ids;
+  }
+
+}
diff --git a/src/Plugin/migrate/destination/FlagCounts.php b/src/Plugin/migrate/destination/FlagCounts.php
new file mode 100644
index 0000000..1af928e
--- /dev/null
+++ b/src/Plugin/migrate/destination/FlagCounts.php
@@ -0,0 +1,66 @@
+<?php
+
+namespace Drupal\flag\Plugin\migrate\destination;
+
+use Drupal\migrate\Plugin\MigrationInterface;
+use Drupal\migrate\Row;
+use Drupal\migrate\Plugin\migrate\destination\DestinationBase;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+
+/**
+ * @MigrateDestination(
+ *   id = "flag_counts"
+ * )
+ */
+class FlagCounts extends DestinationBase implements ContainerFactoryPluginInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) {
+
+    // @todo: Not sure what should happen here.
+
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $migration,
+      $container
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function import(Row $row, array $old_destination_id_values = array()) {
+
+    // @todo Save flag counts
+
+    return array();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getIds() {
+    $ids['flag_name']['type'] = 'string';
+    $ids['entity_id']['type'] = 'integer';
+    return $ids;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fields(MigrationInterface $migration = NULL) {
+    return [
+      'flag_id' => '',
+      'entity_type' => 'The flag type, for example "node", "comment", or "user".',
+      'entity_id' => 'The unique ID of the flagged entity, for example the uid, cid, or nid.',
+      'count' => 'The number of times this object has been flagged for this flag.',
+      'last_updated' => 'The UNIX time stamp representing when the flag was last updated.',
+    ];
+  }
+
+}
diff --git a/src/Plugin/migrate/source/d7/Flag.php b/src/Plugin/migrate/source/d7/Flag.php
new file mode 100644
index 0000000..ac50738
--- /dev/null
+++ b/src/Plugin/migrate/source/d7/Flag.php
@@ -0,0 +1,86 @@
+<?php
+
+namespace Drupal\flag\Plugin\migrate\source\d7;
+
+use Drupal\migrate\Row;
+use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
+
+/**
+ * Drupal 7 Flag source from database.
+ *
+ * @MigrateSource(
+ *   id = "d7_flag",
+ *   source_provider = "flag"
+ * )
+ */
+class Flag extends DrupalSqlBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function query() {
+    return $this->select('flag', 'f')->fields('f');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fields() {
+    return array(
+      'fid' => $this->t('The unique ID for this particular flag.'),
+      'entity_type' => $this->t(''),
+      'name' => $this->t(''),
+      'title' => $this->t(''),
+      'global' => $this->t('Whether this flag state should act as a single toggle to all users across the site.'),
+      'options' => $this->t(''),
+      'default_weight' => $this->t('Default weight applied to new items.'),
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function prepareRow(Row $row) {
+    $source_options = unserialize($row->getSourceProperty('options'));
+    // Flag: entity_type
+    // @todo: Hardcoding 'entity:' for now. Should we be setting this dynamically?
+    $flag_entity_type = $row->getSourceProperty('entity_type');
+    $row->setSourceProperty('flag_type', 'entity:' . $flag_entity_type);
+    // Use D7 flag options as source data.
+    $row->setSourceProperty('options', $source_options);
+    // Flag: bundles
+    $bundles = array();
+    $d7_bundles = $this->select('flag_types', 'ft')
+      ->fields('ft', array('type'))
+      ->condition('fid', $row->getSourceProperty('fid'))
+      ->execute();
+    while($bundle = $d7_bundles->fetchAssoc()) {
+      $bundles[] = $bundle['type'];
+    }
+    $row->setSourceProperty('bundles', $bundles);
+    // Flag: flagTypeConfig
+    $flagTypeConfig = array();
+    $flagTypeConfig['show_in_links'] = $source_options['show_in_links'];
+    $flagTypeConfig['show_as_field'] = $source_options['show_as_field'];
+    $flagTypeConfig['show_on_form'] = $source_options['show_on_form'];
+    $flagTypeConfig['access_author'] = $source_options['access_author'];
+    $flagTypeConfig['show_contextual_link'] = $source_options['show_contextual_link'];
+    $row->setSourceProperty('flagTypeConfig', $flagTypeConfig);
+    // Flag: linkTypeConfig
+    $linkTypeConfig = array();
+    $linkTypeConfig['flag_confirmation'] = $source_options['flag_confirmation'];
+    $linkTypeConfig['unflag_confirmation'] = $source_options['unflag_confirmation'];
+    $row->setSourceProperty('linkTypeConfig', $linkTypeConfig);
+
+    return parent::prepareRow($row);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getIds() {
+    $ids['fid']['type'] = 'integer';
+    return $ids;
+  }
+
+}
diff --git a/src/Plugin/migrate/source/d7/FlagCounts.php b/src/Plugin/migrate/source/d7/FlagCounts.php
new file mode 100644
index 0000000..97e4d70
--- /dev/null
+++ b/src/Plugin/migrate/source/d7/FlagCounts.php
@@ -0,0 +1,62 @@
+<?php
+
+namespace Drupal\flag\Plugin\migrate\source\d7;
+
+use Drupal\migrate\Row;
+use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
+
+/**
+ * Drupal 7 Flag counts source from database.
+ *
+ * @MigrateSource(
+ *   id = "d7_flag_counts",
+ *   source_provider = "flag"
+ * )
+ */
+class FlagCounts extends DrupalSqlBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function query() {
+    return $this->select('flag_counts', 'fc')->fields('fc');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fields() {
+    return array(
+      'fid' => $this->t(''),
+      'entity_type' => $this->t(''),
+      'entity_id' => $this->t('The unique ID of the flagged entity, for example the uid, cid, or nid.'),
+      'count' => $this->t('The number of times this object has been flagged for this flag.'),
+      'last_updated' => $this->t('The UNIX time stamp representing when the flag was last updated. '),
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function prepareRow(Row $row) {
+    // Flag count: flag_name
+    $d7_flag_name = $this->select('flag', 'f')
+      ->fields('f', array('name'))
+      ->condition('fid', $row->getSourceProperty('fid'))
+      ->execute();
+    $flag_name = $d7_flag_name->fetchField();
+    $row->setSourceProperty('flag_name', $flag_name);
+
+    return parent::prepareRow($row);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getIds() {
+    $ids['fid']['type'] = 'integer';
+    $ids['entity_id']['type'] = 'integer';
+    return $ids;
+  }
+
+}
diff --git a/src/Plugin/migrate/source/d7/Flagging.php b/src/Plugin/migrate/source/d7/Flagging.php
new file mode 100644
index 0000000..1c61c63
--- /dev/null
+++ b/src/Plugin/migrate/source/d7/Flagging.php
@@ -0,0 +1,71 @@
+<?php
+
+namespace Drupal\flag\Plugin\migrate\source\d7;
+
+use Drupal\migrate\Row;
+use Drupal\migrate_drupal\Plugin\migrate\source\d7\FieldableEntity;
+
+/**
+ * Drupal 7 Flag source from database.
+ *
+ * @MigrateSource(
+ *   id = "d7_flagging",
+ *   source_provider = "flag"
+ * )
+ */
+class Flagging extends FieldableEntity {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function query() {
+    return $this->select('flagging', 'f')->fields('f');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fields() {
+    return array(
+      'flagging_id' => $this->t('The unique ID for this particular tag.'),
+      'fid' => $this->t('The unique flag ID this object has been flagged with, from flag.'),
+      'entity_type' => $this->t(''),
+      'entity_id' => $this->t('The unique ID of the flagged entity, for example the uid, cid, or nid.'),
+      'uid' => $this->t('The user ID by whom this object was flagged.'),
+      'sid' => $this->t('The user’s numeric sid from the session_api table.'),
+      'timestamp' => $this->t('The UNIX time stamp representing when the flag was set.'),
+      'weight' => $this->t(''),
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function prepareRow(Row $row) {
+    // Flagging: flag_name
+    $d7_flag_name = $this->select('flag', 'f')
+      ->fields('f', array('name'))
+      ->condition('fid', $row->getSourceProperty('fid'))
+      ->execute();
+    $flag_name = $d7_flag_name->fetchField();
+    $row->setSourceProperty('flag_name', $flag_name);
+    // Flagging: global
+    $d7_flag_global = $this->select('flag', 'f')
+      ->fields('f', array('global'))
+      ->condition('fid', $row->getSourceProperty('fid'))
+      ->execute();
+    $global = $d7_flag_global->fetchField();
+    $row->setSourceProperty('global', $global);
+
+    return parent::prepareRow($row);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getIds() {
+    $ids['flagging_id']['type'] = 'integer';
+    return $ids;
+  }
+
+}
