diff --git a/migration_templates/d7_paragraph.yml b/migration_templates/d7_paragraph.yml
new file mode 100644
index 0000000..a310e88
--- /dev/null
+++ b/migration_templates/d7_paragraph.yml
@@ -0,0 +1,23 @@
+id: d7_paragraph
+label: Paragraphs
+migration_tags:
+  - Drupal 7
+builder:
+  plugin: d7_paragraph
+source:
+  plugin: d7_paragraph
+process:
+  id: item_id
+  type: bundle
+  revision_id: revision_id
+  langcode:
+    plugin: default_value
+    source: language
+    default_value: "und"
+destination:
+  plugin: entity:paragraph
+migration_dependencies:
+  required:
+    - d7_user
+    - d7_paragraph_type
+    - d7_paragraph_field_instance
diff --git a/migration_templates/d7_paragraph_field.yml b/migration_templates/d7_paragraph_field.yml
new file mode 100644
index 0000000..9591d47
--- /dev/null
+++ b/migration_templates/d7_paragraph_field.yml
@@ -0,0 +1,53 @@
+id: d7_paragraph_field
+label: Paragraph field configuration
+migration_tags:
+  - Drupal 7
+source:
+  plugin: d7_paragraph_field
+  constants:
+    status: true
+    langcode: und
+process:
+  entity_type:
+    plugin: static_map
+    source: entity_type
+    bypass: true
+    map:
+      paragraphs_item: paragraph
+  status: 'constants/status'
+  langcode: 'constants/langcode'
+  field_name: field_name
+  type:
+    plugin: static_map
+    source: type
+    map:
+      date: datetime
+      datestamp: datetime
+      datetime: datetime
+      email: email
+      file: file
+      image: image
+      link_field: link
+      list_boolean: boolean
+      list_integer: list_integer
+      list_text: list_string
+      number_integer: integer
+      number_decimal: decimal
+      number_float: float
+      paragraphs: entity_reference_revisions
+      paragraphs_item: paragraph
+      phone: telephone
+      taxonomy_term_reference: entity_reference
+      text: text
+      text_long: text_long
+      text_with_summary: text_with_summary
+  translatable: translatable
+  cardinality: cardinality
+  settings:
+    plugin: d7_paragraph_field_settings
+destination:
+  plugin: entity:field_storage_config
+migration_dependencies:
+  required:
+    - d7_paragraph_type
+    - d7_field
diff --git a/migration_templates/d7_paragraph_field_instance.yml b/migration_templates/d7_paragraph_field_instance.yml
new file mode 100644
index 0000000..958cea8
--- /dev/null
+++ b/migration_templates/d7_paragraph_field_instance.yml
@@ -0,0 +1,37 @@
+id: d7_paragraph_field_instance
+label: Paragraph field instance configuration
+migration_tags:
+  - Drupal 7
+source:
+  plugin: d7_paragraph_field_instance
+  constants:
+    status: true
+process:
+  entity_type:
+    plugin: static_map
+    source: entity_type
+    bypass: true
+    map:
+      paragraphs_item: paragraph
+  field_name: field_name
+  bundle: bundle
+  label: label
+  description: description
+  required: required
+  status: 'constants/status'
+  settings:
+    plugin: d7_paragraph_field_instance_settings
+    source:
+      - instance_settings
+      - widget_settings
+  default_value_function: ''
+  default_value:
+    plugin: d7_field_instance_defaults
+    source:
+      - default_value
+      - widget_settings
+destination:
+  plugin: entity:field_config
+migration_dependencies:
+  required:
+    - d7_paragraph_field
diff --git a/migration_templates/d7_paragraph_revision.yml b/migration_templates/d7_paragraph_revision.yml
new file mode 100644
index 0000000..135de93
--- /dev/null
+++ b/migration_templates/d7_paragraph_revision.yml
@@ -0,0 +1,21 @@
+id: d7_paragraph_revision
+label: Paragraph revisions
+migration_tags:
+  - Drupal 7
+builder:
+  plugin: d7_paragraph
+source:
+  plugin: d7_paragraph_revision
+process:
+  id: item_id
+  type: bundle
+  revision_id: revision_id
+  langcode:
+    plugin: default_value
+    source: language
+    default_value: "und"
+destination:
+  plugin: entity_revision:paragraph
+migration_dependencies:
+  required:
+    - d7_paragraph:*
diff --git a/migration_templates/d7_paragraph_set.yml b/migration_templates/d7_paragraph_set.yml
new file mode 100644
index 0000000..59ad670
--- /dev/null
+++ b/migration_templates/d7_paragraph_set.yml
@@ -0,0 +1,14 @@
+id: d7_paragraph_set
+label: Paragraph sets
+migration_tags:
+  - Drupal 7
+builder:
+  plugin: d7_paragraph_set
+source:
+  plugin: d7_node
+process:
+  nid: nid
+  vid: vid
+  type: type
+destination:
+  plugin: entity:node
diff --git a/migration_templates/d7_paragraph_type.yml b/migration_templates/d7_paragraph_type.yml
new file mode 100644
index 0000000..8c94520
--- /dev/null
+++ b/migration_templates/d7_paragraph_type.yml
@@ -0,0 +1,11 @@
+id: d7_paragraph_type
+label: Paragraph type configuration
+migration_tags:
+  - Drupal 7
+source:
+  plugin: d7_paragraph_type
+process:
+  id: bundle
+  label: name
+destination:
+  plugin: entity:paragraphs_type
diff --git a/src/Plugin/migrate/builder/Paragraph.php b/src/Plugin/migrate/builder/Paragraph.php
new file mode 100644
index 0000000..60d7e9d
--- /dev/null
+++ b/src/Plugin/migrate/builder/Paragraph.php
@@ -0,0 +1,57 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\paragraphs\Plugin\migrate\builder\Paragraph.
+ */
+
+namespace Drupal\paragraphs\Plugin\migrate\builder;
+
+use Drupal\migrate\Entity\Migration;
+use Drupal\migrate_drupal\Plugin\migrate\builder\CckBuilder;
+
+/**
+ * @PluginID("d7_paragraph")
+ */
+class Paragraph extends CckBuilder {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildMigrations(array $template) {
+    $migrations = [];
+
+    // Read all field instance definitions in the source database.
+    $fields = array();
+    foreach ($this->getSourcePlugin('d7_paragraph_field_instance', $template['source']) as $field) {
+      $info = $field->getSource();
+      $fields[$info['entity_type']][$info['bundle']][$info['field_name']] = $info;
+    }
+
+    foreach ($this->getSourcePlugin('d7_paragraph_type', $template['source']) as $paragraph_type) {
+      $bundle = $paragraph_type->getSourceProperty('bundle');
+      $values = $template;
+      $values['id'] .= '__' . $bundle;
+      $values['label'] = $this->t('@label (@type)', ['@label' => $values['label'], '@type' => $paragraph_type->getSourceProperty('name')]);
+      $values['source']['paragraph_type'] = $bundle;
+      $migration = Migration::create($values);
+
+      if (isset($fields['paragraphs_item'][$bundle])) {
+        foreach ($fields['paragraphs_item'][$bundle] as $field => $data) {
+          if ($this->cckPluginManager->hasDefinition($data['type'])) {
+            $this->getCckPlugin($data['type'])
+              ->processCckFieldValues($migration, $field, $data);
+          }
+          else {
+            $migration->setProcessOfProperty($field, $field);
+          }
+        }
+      }
+
+      $migrations[] = $migration;
+    }
+
+    return $migrations;
+  }
+
+}
diff --git a/src/Plugin/migrate/builder/ParagraphSet.php b/src/Plugin/migrate/builder/ParagraphSet.php
new file mode 100644
index 0000000..ad6a955
--- /dev/null
+++ b/src/Plugin/migrate/builder/ParagraphSet.php
@@ -0,0 +1,56 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\paragraphs\Plugin\migrate\builder\ParagraphSet.
+ */
+
+namespace Drupal\paragraphs\Plugin\migrate\builder;
+
+use Drupal\migrate\Entity\Migration;
+
+/**
+ * @PluginID("d7_paragraph_set")
+ */
+class ParagraphSet extends Paragraph {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildMigrations(array $template) {
+    $migrations = [];
+
+    // Read all field instance definitions in the source database.
+    $fields = array();
+    foreach ($this->getSourcePlugin('d7_paragraph_field_instance', $template['source']) as $field) {
+      $info = $field->getSource();
+      $fields[$info['entity_type']][$info['bundle']][$info['field_name']] = $info;
+    }
+
+    $entity_type_source = 'd7_node_type';
+    $entity_type = 'node';
+    $entity_name = 'Node';
+    foreach ($this->getSourcePlugin($entity_type_source, $template['source']) as $node_type) {
+      $bundle = $node_type->getSourceProperty('type');
+      $values = $template;
+      $values['id'] .= '__' . $entity_type . '__' . $bundle;
+      $values['label'] = $this->t('@label (@entity @type)', ['@label' => $values['label'], '@entity' => $entity_name, '@type' => $node_type->getSourceProperty('name')]);
+      $values['source']['node_type'] = $bundle;
+      $migration = Migration::create($values);
+
+      if (isset($fields[$entity_type][$bundle])) {
+        foreach ($fields[$entity_type][$bundle] as $field => $data) {
+          $migration->setProcessOfProperty($field, array(
+            'plugin' => 'paragraph_reference',
+            'source' => $field
+          ));
+        }
+      }
+
+      $migrations[] = $migration;
+    }
+
+    return $migrations;
+  }
+
+}
diff --git a/src/Plugin/migrate/destination/EntityParagraphType.php b/src/Plugin/migrate/destination/EntityParagraphType.php
new file mode 100644
index 0000000..a5c7283
--- /dev/null
+++ b/src/Plugin/migrate/destination/EntityParagraphType.php
@@ -0,0 +1,20 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\paragraphs\Plugin\migrate\destination\EntityParagraphType.
+ */
+
+namespace Drupal\paragraphs\Plugin\migrate\destination;
+
+use Drupal\migrate\Plugin\migrate\destination\EntityConfigBase;
+use Drupal\migrate\Row;
+
+/**
+ * @MigrateDestination(
+ *   id = "entity:paragraphs_type"
+ * )
+ */
+class EntityParagraphType extends EntityConfigBase {
+
+}
diff --git a/src/Plugin/migrate/process/ParagraphFieldInstanceSettings.php b/src/Plugin/migrate/process/ParagraphFieldInstanceSettings.php
new file mode 100644
index 0000000..acdc55f
--- /dev/null
+++ b/src/Plugin/migrate/process/ParagraphFieldInstanceSettings.php
@@ -0,0 +1,60 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\paragraphs\Plugin\migrate\process\ParagraphFieldInstanceSettings.
+ */
+
+namespace Drupal\paragraphs\Plugin\migrate\process;
+
+use Drupal\field\Plugin\migrate\process\d7\FieldInstanceSettings;
+use Drupal\migrate\MigrateExecutableInterface;
+use Drupal\migrate\Row;
+
+/**
+ * @MigrateProcessPlugin(
+ *   id = "d7_paragraph_field_instance_settings"
+ * )
+ */
+class ParagraphFieldInstanceSettings extends FieldInstanceSettings {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
+    list($instance_settings, $widget_settings) = $value;
+    $widget_type = $widget_settings['type'];
+
+    if ('paragraphs_embed' == $widget_type) {
+      $settings = $instance_settings;
+      $settings['handler'] = 'default:paragraph';
+      $settings['handler_settings']['target_bundles'] = array();
+      $settings['handler_settings']['target_bundles_drag_drop'] = array();
+
+      $paragraph_bundle_ids = array_keys(\Drupal::entityManager()->getBundleInfo('paragraph'));
+      $weight = count($paragraph_bundle_ids) + 1;
+
+      if (isset($paragraph_bundle_ids) && count($paragraph_bundle_ids) > 0) {
+        foreach ($paragraph_bundle_ids as $paragraph_bundle_id) {
+          $settings['handler_settings']['target_bundles'][$paragraph_bundle_id] = $paragraph_bundle_id;
+          $enabled = FALSE;
+          if (isset($settings['allowed_bundles'][$paragraph_bundle_id])) {
+            $enabled = $settings['allowed_bundles'][$paragraph_bundle_id] === $paragraph_bundle_id;
+          }
+          $settings['handler_settings']['target_bundles_drag_drop'][$paragraph_bundle_id] = array(
+            'weight' => $weight,
+            'enabled' => $enabled
+          );
+
+          $weight++;
+        }
+      }
+    }
+    else {
+      $settings = parent::transform($value, $migrate_executable, $row, $destination_property);
+    }
+
+    return $settings;
+  }
+
+}
diff --git a/src/Plugin/migrate/process/ParagraphFieldSettings.php b/src/Plugin/migrate/process/ParagraphFieldSettings.php
new file mode 100644
index 0000000..388c4ff
--- /dev/null
+++ b/src/Plugin/migrate/process/ParagraphFieldSettings.php
@@ -0,0 +1,37 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\paragraphs\Plugin\migrate\process\ParagraphFieldSettings.
+ */
+
+namespace Drupal\paragraphs\Plugin\migrate\process;
+
+use Drupal\field\Plugin\migrate\process\d7\FieldSettings;
+use Drupal\migrate\MigrateExecutableInterface;
+use Drupal\migrate\Row;
+
+/**
+ * @MigrateProcessPlugin(
+ *   id = "d7_paragraph_field_settings"
+ * )
+ */
+class ParagraphFieldSettings extends FieldSettings {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
+    $value = $row->getSourceProperty('settings');
+
+    if ('paragraphs' == $row->getSourceProperty('type')) {
+      $value['target_type'] = 'paragraph';
+    }
+    else {
+      $value = parent::transform($value, $migrate_executable, $row, $destination_property);
+    }
+
+    return $value;
+  }
+
+}
diff --git a/src/Plugin/migrate/process/ParagraphReference.php b/src/Plugin/migrate/process/ParagraphReference.php
new file mode 100644
index 0000000..4d98ec6
--- /dev/null
+++ b/src/Plugin/migrate/process/ParagraphReference.php
@@ -0,0 +1,41 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\paragraphs\Plugin\migrate\process\ParagraphReference.
+ */
+
+namespace Drupal\paragraphs\Plugin\migrate\process;
+
+use Drupal\migrate\ProcessPluginBase;
+use Drupal\migrate\MigrateExecutableInterface;
+use Drupal\migrate\Row;
+
+/**
+ * This plugin copies from the source to the destination.
+ *
+ * @MigrateProcessPlugin(
+ *   id = "paragraph_reference"
+ * )
+ */
+class ParagraphReference extends ProcessPluginBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
+    $new_value = $value;
+    if (isset($new_value['value'])) {
+      $new_value['target_id'] = $new_value['value'];
+      unset($new_value['value']);
+    }
+
+    if (isset($new_value['revision_id'])) {
+      $new_value['target_revision_id'] = $new_value['revision_id'];
+      unset($new_value['revision_id']);
+    }
+
+    return $new_value;
+  }
+
+}
diff --git a/src/Plugin/migrate/source/Paragraph.php b/src/Plugin/migrate/source/Paragraph.php
new file mode 100644
index 0000000..3dc2f72
--- /dev/null
+++ b/src/Plugin/migrate/source/Paragraph.php
@@ -0,0 +1,84 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\paragraphs\Plugin\migrate\source\Paragraph.
+ */
+
+namespace Drupal\paragraphs\Plugin\migrate\source;
+
+use Drupal\migrate\Row;
+use Drupal\migrate_drupal\Plugin\migrate\source\d7\FieldableEntity;
+
+
+/**
+ * Drupal 7 paragraph source from database.
+ *
+ * @MigrateSource(
+ *   id = "d7_paragraph",
+ *   source_provider = "paragraphs"
+ * )
+ */
+class Paragraph extends FieldableEntity {
+
+  /**
+   * The join options between the paragraphs_item and the paragraphs_item_revision table.
+   */
+  const JOIN = 'p.revision_id = pr.revision_id';
+
+  /**
+   * {@inheritdoc}
+   */
+  public function query() {
+    // Select node in its last revision.
+    $query = $this->select('paragraphs_item_revision', 'pr')
+      ->fields('p', array(
+        'item_id',
+        'bundle',
+      ))
+      ->fields('pr', array(
+        'revision_id',
+      ));
+    $query->innerJoin('paragraphs_item', 'p', static::JOIN);
+
+    if (isset($this->configuration['paragraph_type'])) {
+      $query->condition('bundle', $this->configuration['paragraph_type']);
+    }
+
+    return $query;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function prepareRow(Row $row) {
+    // Get Field API field values.
+    foreach (array_keys($this->getFields('paragraphs_item', $row->getSourceProperty('bundle'))) as $field) {
+      $nid = $row->getSourceProperty('item_id');
+      $vid = $row->getSourceProperty('revision_id');
+      $row->setSourceProperty($field, $this->getFieldValues('paragraphs_item', $field, $nid, $vid));
+    }
+    return parent::prepareRow($row);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fields() {
+    $fields = array(
+      'item_id' => $this->t('Paragraph ID'),
+      'bundle' => $this->t('Type'),
+    );
+    return $fields;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getIds() {
+    $ids['item_id']['type'] = 'integer';
+    $ids['item_id']['alias'] = 'p';
+    return $ids;
+  }
+
+}
diff --git a/src/Plugin/migrate/source/ParagraphField.php b/src/Plugin/migrate/source/ParagraphField.php
new file mode 100644
index 0000000..4a09a6f
--- /dev/null
+++ b/src/Plugin/migrate/source/ParagraphField.php
@@ -0,0 +1,34 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\paragraphs\Plugin\migrate\source\ParagraphField.
+ */
+
+namespace Drupal\paragraphs\Plugin\migrate\source;
+
+use Drupal\migrate\Row;
+use Drupal\field\Plugin\migrate\source\d7\Field;
+
+/**
+ * Drupal 7 Paragraph field source from database.
+ *
+ * @MigrateSource(
+ *   id = "d7_paragraph_field",
+ * )
+ */
+class ParagraphField extends Field {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function query() {
+    $query = parent::query();
+    $group = $query->orConditionGroup()
+      ->condition('fc.type', 'paragraphs')
+      ->condition('fci.entity_type', 'paragraphs_item');
+    $query->condition($group);
+    return $query;
+  }
+
+}
diff --git a/src/Plugin/migrate/source/ParagraphFieldInstance.php b/src/Plugin/migrate/source/ParagraphFieldInstance.php
new file mode 100644
index 0000000..989f9ee
--- /dev/null
+++ b/src/Plugin/migrate/source/ParagraphFieldInstance.php
@@ -0,0 +1,34 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\paragraphs\Plugin\migrate\source\ParagraphFieldInstance.
+ */
+
+namespace Drupal\paragraphs\Plugin\migrate\source;
+
+use Drupal\migrate\Row;
+use Drupal\field\Plugin\migrate\source\d7\FieldInstance;
+
+/**
+ * Drupal 7 Paragraph types source from database.
+ *
+ * @MigrateSource(
+ *   id = "d7_paragraph_field_instance",
+ * )
+ */
+class ParagraphFieldInstance extends FieldInstance {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function query() {
+    $query = parent::query();
+    $group = $query->orConditionGroup()
+      ->condition('fc.type', 'paragraphs')
+      ->condition('fci.entity_type', 'paragraphs_item');
+    $query->condition($group);
+    return $query;
+  }
+
+}
diff --git a/src/Plugin/migrate/source/ParagraphRevision.php b/src/Plugin/migrate/source/ParagraphRevision.php
new file mode 100644
index 0000000..242fc14
--- /dev/null
+++ b/src/Plugin/migrate/source/ParagraphRevision.php
@@ -0,0 +1,34 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\paragraphs\Plugin\migrate\source\ParagraphRevision.
+ */
+
+namespace Drupal\paragraphs\Plugin\migrate\source;
+
+/**
+ * Drupal 7 node revision source from database.
+ *
+ * @MigrateSource(
+ *   id = "d7_paragraph_revision",
+ *   source_provider = "paragraphs"
+ * )
+ */
+class ParagraphRevision extends Paragraph {
+
+  /**
+   * The join options between the paragraphs_item and the paragraphs_item_revisions_table.
+   */
+  const JOIN = 'p.item_id = pr.item_id AND p.revision_id <> pr.revision_id';
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getIds() {
+    $ids['revision_id']['type'] = 'integer';
+    $ids['revision_id']['alias'] = 'pr';
+    return $ids;
+  }
+
+}
diff --git a/src/Plugin/migrate/source/ParagraphType.php b/src/Plugin/migrate/source/ParagraphType.php
new file mode 100644
index 0000000..66ec24a
--- /dev/null
+++ b/src/Plugin/migrate/source/ParagraphType.php
@@ -0,0 +1,48 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\paragraphs\Plugin\migrate\source\ParagraphType.
+ */
+
+namespace Drupal\paragraphs\Plugin\migrate\source;
+
+use Drupal\migrate\Row;
+use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
+
+/**
+ * Drupal 7 Paragraph field instances source from database.
+ *
+ * @MigrateSource(
+ *   id = "d7_paragraph_type",
+ * )
+ */
+class ParagraphType extends DrupalSqlBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function query() {
+    return $this->select('paragraphs_bundle', 't')->fields('t');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fields() {
+    return array(
+      'bundle' => $this->t('Machine name of the paragraph type.'),
+      'name' => $this->t('Human name of the paragraph type.'),
+      'locked' => $this->t('Flag.'),
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getIds() {
+    $ids['bundle']['type'] = 'string';
+    return $ids;
+  }
+
+}
