diff --git a/ParagraphsItemEntity.inc b/ParagraphsItemEntity.inc
index 14ff401..c437c1c 100644
--- a/ParagraphsItemEntity.inc
+++ b/ParagraphsItemEntity.inc
@@ -350,10 +350,6 @@ class ParagraphsItemEntity extends Entity {
    *   revision updates might be skipped. Use with care.
    */
   public function save($skip_host_save = FALSE) {
-    // Make sure we have a host entity during creation.
-    if (!empty($this->is_new) && !(isset($this->hostEntityId) || isset($this->hostEntity) || isset($this->hostEntityRevisionId))) {
-      throw new Exception("Unable to create a paragraphs item without a given host entity.");
-    }
 
     // Only save directly if we are told to skip saving the host entity. Else,
     // we always save via the host as saving the host might trigger saving
diff --git a/migrate/destinations/MigrateDestinationParagraphsItem.inc b/migrate/destinations/MigrateDestinationParagraphsItem.inc
new file mode 100644
index 0000000..598e257
--- /dev/null
+++ b/migrate/destinations/MigrateDestinationParagraphsItem.inc
@@ -0,0 +1,195 @@
+<?php
+
+/**
+ * @file
+ * Provides basic class for importing Paragraphs via Migrate API.
+ */
+
+/**
+ * Destination class implementing migration into field_collection.
+ */
+class MigrateDestinationParagraphsItem extends MigrateDestinationEntity {
+
+  /**
+   * The bundle (node type, vocabulary, etc.) of the destination.
+   *
+   * @var string
+   */
+  protected $field_name;
+  public function getFieldName() {
+    return $this->field_name;
+  }
+
+  static public function getKeySchema() {
+    return array(
+      'item_id' => array(
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'description' => 'ID of field collection item',
+      ),
+    );
+  }
+
+  /**
+   * Basic initialization.
+   *
+   * @param array $options
+   *   (optional) Options applied to collections.
+   */
+  public function __construct($bundle, array $options = array()) {
+    parent::__construct('paragraphs_item', $bundle, $options);
+
+    $this->field_name = isset($options['field_name']) ? $options['field_name'] : '';
+  }
+
+  /**
+   * Return an options array for node destinations.
+   *
+   * @param string $language
+   *  Default language for nodes created via this destination class.
+   * @param string $text_format
+   *  Default text format for nodes created via this destination class.
+   */
+  static public function options($language, $text_format) {
+    return compact('language', 'text_format');
+  }
+
+
+  /**
+   * Returns a list of fields available to be mapped for the node type (bundle)
+   *
+   * @param Migration $migration
+   *  Optionally, the migration containing this destination.
+   * @return array
+   *  Keys: machine names of the fields (to be passed to addFieldMapping)
+   *  Values: Human-friendly descriptions of the fields.
+   */
+  public function fields($migration = NULL) {
+    $fields = array();
+
+    $fields['field_name'] = t('Field name');
+    $fields['archived'] = t('Archived status of the paragraph item');
+
+    $fields += migrate_handler_invoke_all('Entity', 'fields', $this->entityType, $this->bundle, $migration);
+    $fields += migrate_handler_invoke_all('ParagraphsItem', 'fields', $this->entityType, $this->bundle, $migration);
+
+    return $fields;
+  }
+
+  /**
+   * Delete a batch of nodes at once.
+   *
+   * @param $nids
+   *  Array of node IDs to be deleted.
+   */
+  public function bulkRollback(array $item_ids) {
+    migrate_instrument_start('paragraphs_item_delete_multiple');
+    $this->prepareRollback($item_ids);
+    entity_delete_multiple('paragraphs_item', $item_ids);
+    $this->completeRollback($item_ids);
+    migrate_instrument_stop('paragraphs_item_delete_multiple');
+  }
+
+  /**
+   * Import a single node.
+   *
+   * @param $node
+   *  Node object to build. Prefilled with any fields mapped in the Migration.
+   * @param $row
+   *  Raw source data object - passed through to prepare/complete handlers.
+   * @return array
+   *  Array of key fields (nid only in this case) of the node that was saved if
+   *  successful. FALSE on failure.
+   */
+  public function import(stdClass $paragraphs_item, stdClass $row) {
+    $migration = Migration::currentMigration();
+
+    // Updating previously-migrated content?
+    if (isset($row->migrate_map_destid1)) {
+      if (isset($paragraphs_item->item_id)) {
+        if ($paragraphs_item->item_id != $row->migrate_map_destid1) {
+          throw new MigrateException(t("Incoming item_id !item_id and map destination item_id !destid1 don't match",
+            array('!item_id' => $paragraphs_item->item_id, '!destid1' => $row->migrate_map_destid1)));
+        }
+      }
+      else {
+        $paragraphs_item->item_id = $row->migrate_map_destid1;
+        $paragraphs_item->is_new = FALSE;
+        $paragraphs_item->is_new_revision = TRUE;
+      }
+    }
+
+    // When updating, we make sure that id exists.
+    if ($migration->getSystemOfRecord() == Migration::DESTINATION) {
+      if (!isset($paragraphs_item->item_id)) {
+        throw new MigrateException(t('System-of-record is DESTINATION, but no destination item_id provided'));
+      }
+
+      // Hold raw original values for later.
+      $raw_paragraph = $paragraphs_item;
+
+      // This entity will be the one, we party on.
+      $entity = paragraphs_item_load($paragraphs_item->item_id);
+      if (empty($entity)) {
+        throw new MigrateException(t('System-of-record is DESTINATION, but paragraphs item !item_id does not exist',
+          array('!item_id' => $paragraphs_item->item_id)));
+      }
+    }
+    // Provide defaults for SOURCE d
+    else {
+      // Set some default properties.
+      $defaults = array(
+        'language' => $this->language,
+        'bundle' => $this->bundle,
+        'field_name' => $this->field_name,
+        'archived' => 0,
+      );
+      foreach ($defaults as $field => $value) {
+        if (!isset($paragraphs_item->$field)) {
+          $paragraphs_item->$field = $value;
+        }
+      }
+    }
+
+    $this->prepare($paragraphs_item, $row);
+
+    if ($migration->getSystemOfRecord() == Migration::DESTINATION) {
+      foreach ($raw_paragraph as $field => $value) {
+        $entity->$field = $paragraphs_item->$field;
+      }
+    }
+    else {
+
+      // This will be the entity we party on.
+      $entity = entity_create('paragraphs_item', (array) $paragraphs_item);
+    }
+
+
+    if (isset($entity->item_id) && $entity->item_id) {
+      $updating = TRUE;
+    }
+    else {
+      $updating = FALSE;
+    }
+
+    migrate_instrument_start('paragraphs_item_save');
+    $entity->save(TRUE);
+    migrate_instrument_stop('paragraphs_item_save');
+
+    $this->complete($entity, $row);
+    if (isset($entity->item_id) && $entity->item_id > 0) {
+      $return = array($entity->item_id);
+      if ($updating) {
+        $this->numUpdated++;
+      }
+      else {
+        $this->numCreated++;
+      }
+    }
+    else {
+      $return = FALSE;
+    }
+    return $return;
+  }
+}
diff --git a/migrate/fields/ParagraphsMigrateParagraphsFieldHandler.inc b/migrate/fields/ParagraphsMigrateParagraphsFieldHandler.inc
new file mode 100644
index 0000000..165a593
--- /dev/null
+++ b/migrate/fields/ParagraphsMigrateParagraphsFieldHandler.inc
@@ -0,0 +1,119 @@
+<?php
+
+/**
+ * Class ParagraphsMigrateParagraphsFieldHandler
+ *
+ * Provides migrate field handler for paragraphs field.
+ */
+class ParagraphsMigrateParagraphsFieldHandler extends MigrateSimpleFieldHandler {
+
+  /**
+   * @inheritdoc
+   */
+  public function __construct() {
+    parent::__construct(array(
+      'value_key' => 'value',
+      'skip_empty' => TRUE,
+    ));
+    $this->registerTypes(array('paragraphs'));
+  }
+
+  /**
+   * Provide additional fields for migration.
+   *
+   * @param $type
+   * @param $instance
+   * @param null $migration
+   *
+   * @return array
+   */
+  public function fields($type, $instance, $migration = NULL) {
+    return array(
+      'revision_id' => t('Option: Provide optional revision id.'),
+    );
+  }
+
+  /**
+   * @inheritdoc
+   */
+  protected function notNull($value) {
+    return !is_null($value) && $value !== FALSE;
+  }
+
+  /**
+   * @inheritdoc
+   */
+  public function prepare($entity, array $field_info, array $instance, array $values) {
+    $arguments = array();
+    if (isset($values['arguments'])) {
+      $arguments = $values['arguments'];
+      unset($values['arguments']);
+    }
+    $language = $this->getFieldLanguage($entity, $field_info, $arguments);
+
+    // Let the derived class skip empty values.
+    if ($this->skipEmpty) {
+      $values = array_filter($values, array($this, 'notNull'));
+    }
+
+    // Do not proceed if we got no values.
+    if (empty($values)) {
+      return NULL;
+    }
+
+    $revision_ids = $this->getRevisionIds($values, $arguments);
+
+    // Setup the Field API array for saving.
+    $delta = 0;
+    foreach ($values as $value) {
+      if (is_array($language)) {
+        $current_language = $language[$delta];
+      }
+      else {
+        $current_language = $language;
+      }
+      $return[$current_language][] = array(
+        $this->fieldValueKey => $value,
+        'revision_id' => $revision_ids[$delta],
+      );
+      $delta++;
+    }
+    return isset($return) ? $return : NULL;
+  }
+
+  /**
+   * Helper to get set of revision ids for import.
+   *
+   * @param $values
+   * @param $arguments
+   */
+  protected function getRevisionIds($values, $arguments) {
+    $return = array();
+
+    if (!isset($arguments['revision_id'])) {
+      $arguments['revision_id'] = array();
+    }
+    elseif (!is_array($arguments['revision_id'])) {
+      $arguments['revision_id'] = array($arguments['revision_id']);
+    }
+
+    $revision_ids = db_select('paragraphs_item', 'p')
+      ->fields('p', array('item_id', 'revision_id'))
+      ->condition('item_id', $values)
+      ->execute()
+      ->fetchAllKeyed();
+
+    foreach ($values as $delta => $item_id) {
+      // Get revision ID provided by the migration.
+      if (!empty($arguments['revision_id'][$delta])) {
+        $return[$delta] = $arguments['revision_id'][$delta];
+      }
+      // Provide latest revision id.
+      else {
+        $return[$delta] = $revision_ids[$item_id];
+      }
+    }
+
+    return $return;
+  }
+}
diff --git a/paragraphs.info b/paragraphs.info
index a9a6791..f56aab6 100644
--- a/paragraphs.info
+++ b/paragraphs.info
@@ -6,4 +6,6 @@ dependencies[] = entity
 
 files[] = ParagraphsItemEntity.inc
 files[] = ParagraphsItemMetadataController.inc
+files[] = migrate/destinations/MigrateDestinationParagraphsItem.inc
+files[] = migrate/fields/ParagraphsMigrateParagraphsFieldHandler.inc
 files[] = views/paragraphs_handler_relationship.inc
diff --git a/paragraphs.migrate.inc b/paragraphs.migrate.inc
new file mode 100644
index 0000000..453eef4
--- /dev/null
+++ b/paragraphs.migrate.inc
@@ -0,0 +1,13 @@
+<?php
+
+/**
+ * Implements hook_migrate_api().
+ */
+function paragraphs_migrate_api() {
+  return array(
+    'api' => 2,
+    'field handlers' => array(
+      'ParagraphsMigrateParagraphsFieldHandler',
+    ),
+  );
+}
