diff --git a/includes/commerce_product.inline_entity_form.inc b/includes/commerce_product.inline_entity_form.inc
index 07b5724..5dcb6f2 100644
--- a/includes/commerce_product.inline_entity_form.inc
+++ b/includes/commerce_product.inline_entity_form.inc
@@ -335,6 +335,16 @@ class CommerceProductInlineEntityFormController extends EntityInlineEntityFormCo
   }
 
   /**
+   * Overrides EntityInlineEntityFormController::createClone().
+   */
+  public function createClone($entity) {
+    $cloned_entity = parent::createClone($entity);
+    $cloned_entity->sku = NULL;
+
+    return $cloned_entity;
+  }
+
+  /**
    * Overrides EntityInlineEntityFormController::save().
    *
    * Autogenerates the product title if specified, and then saves the product.
diff --git a/includes/entity.inline_entity_form.inc b/includes/entity.inline_entity_form.inc
index 353faac..89a4246 100644
--- a/includes/entity.inline_entity_form.inc
+++ b/includes/entity.inline_entity_form.inc
@@ -144,6 +144,7 @@ class EntityInlineEntityFormController {
     $defaults['allow_new'] = TRUE;
     $defaults['allow_existing'] = FALSE;
     $defaults['match_operator'] = 'CONTAINS';
+    $defaults['allow_clone'] = FALSE;
     $defaults['delete_references'] = FALSE;
     $labels = $this->defaultLabels();
     $defaults['override_labels'] = FALSE;
@@ -200,12 +201,16 @@ class EntityInlineEntityFormController {
       $form['match_operator']['#access'] = FALSE;
     }
 
+    $form['allow_clone'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Allow users to clone @label.', array('@label' => $labels['plural'])),
+      '#default_value' => isset($this->settings['allow_clone'])? $this->settings['allow_clone'] : FALSE,
+    );
     $form['delete_references'] = array(
       '#type' => 'checkbox',
       '#title' => t('Delete referenced @label when the parent entity is deleted.', array('@label' => $labels['plural'])),
       '#default_value' => $this->settings['delete_references'],
     );
-
     $form['override_labels'] = array(
       '#type' => 'checkbox',
       '#title' => t('Override labels'),
@@ -378,6 +383,44 @@ class EntityInlineEntityFormController {
   }
 
   /**
+   * Creates a clone of the given entity.
+   *
+   * Copies the entity_ui_clone_entity() approach, extending it to unset
+   * additional unique properties.
+   *
+   * @param $entity
+   *   The entity to clone.
+   *
+   * @return
+   *   The unsaved cloned entity.
+   */
+  public function createClone($entity) {
+    $cloned_entity = clone $entity;
+    $cloned_entity->is_new = TRUE;
+
+    $entity_info = entity_get_info($this->entityType);
+    // Make sure the status of a cloned exportable is custom.
+    if (!empty($entity_info['exportable'])) {
+      $status_key = isset($entity_info['entity keys']['status']) ? $entity_info['entity keys']['status'] : 'status';
+      $cloned_entity->$status_key = ENTITY_CUSTOM;
+    }
+    // Unset properties specified as entity keys.
+    foreach (array('id', 'name', 'revision') as $key) {
+      if (!empty($entity_info['entity keys'][$key])) {
+        $cloned_entity->{$entity_info['entity keys'][$key]} = NULL;
+      }
+    }
+    // Unset other common properties.
+    foreach (array('created', 'changed', 'uid', 'revision_timestamp', 'revision_uid') as $property) {
+      if (isset($cloned_entity->{$property})) {
+        $cloned_entity->{$property} = NULL;
+      }
+    }
+
+    return $cloned_entity;
+  }
+
+  /**
    * Permanently saves the given entity.
    *
    * @param $entity
diff --git a/includes/node.inline_entity_form.inc b/includes/node.inline_entity_form.inc
index ceccb3a..4d481cb 100644
--- a/includes/node.inline_entity_form.inc
+++ b/includes/node.inline_entity_form.inc
@@ -85,4 +85,18 @@ class NodeInlineEntityFormController extends EntityInlineEntityFormController {
       $function($entity_form['#entity'], $entity_form, $child_form_state);
     }
   }
+
+  /**
+   * Overrides EntityInlineEntityFormController::createClone().
+   */
+  public function createClone($entity) {
+    global $user;
+
+    $cloned_entity = parent::createClone($entity);
+    $cloned_entity->tnid = NULL;
+    $cloned_entity->name = isset($user->name) ? $user->name : NULL;
+    $cloned_entity->path = NULL;
+
+    return $cloned_entity;
+  }
 }
diff --git a/inline_entity_form.module b/inline_entity_form.module
index 258c4b1..ef2c429 100644
--- a/inline_entity_form.module
+++ b/inline_entity_form.module
@@ -397,7 +397,6 @@ function inline_entity_form_field_widget_form(&$form, &$form_state, $field, $ins
   $widget = $instance['widget'];
   $settings = inline_entity_form_settings($field, $instance);
   $entity_info = entity_get_info($settings['entity_type']);
-  $cardinality = $field['cardinality'];
   $controller = inline_entity_form_get_controller($instance);
   // The current entity type is not supported, execution can't continue.
   if (!$controller) {
@@ -478,6 +477,11 @@ function inline_entity_form_field_widget_form(&$form, &$form_state, $field, $ins
     }
   }
 
+  // Prepare cardinality information.
+  $cardinality = $field['cardinality'];
+  $entity_count = count($form_state['inline_entity_form'][$ief_id]['entities']);
+  $cardinality_reached = ($cardinality > 0 && $entity_count == $cardinality);
+
   // Build the appropriate widget.
   // The "Single value" widget assumes it is operating on a required single
   // value reference field with 1 allowed bundle.
@@ -620,6 +624,25 @@ function inline_entity_form_field_widget_form(&$form, &$form_state, $field, $ins
             '#ief_row_form' => 'edit',
           );
         }
+        // Add the clone button, if allowed.
+        // The clone form follows the same semantics as the create form, so
+        // it's opened below the table.
+        if ($controller->getSetting('allow_clone') && !$cardinality_reached
+          && entity_access('create', $controller->entityType(), $entity)) {
+          $row['actions']['ief_entity_clone'] = array(
+            '#type' => 'submit',
+            '#value' => t('Clone'),
+            '#name' => 'ief-' . $ief_id . '-entity-clone-' . $key,
+            '#limit_validation_errors' => array(array_merge($parents, array('actions'))),
+            '#ajax' => array(
+              'callback' => 'inline_entity_form_get_element',
+              'wrapper' => $wrapper,
+            ),
+            '#submit' => array('inline_entity_form_open_form'),
+            '#ief_row_delta' => $key,
+            '#ief_form' => 'clone',
+          );
+        }
 
         // If 'allow_existing' is on, the default removal operation is unlink
         // and the access check for deleting happens inside the controller
@@ -643,7 +666,6 @@ function inline_entity_form_field_widget_form(&$form, &$form_state, $field, $ins
       }
     }
 
-    $entity_count = count($form_state['inline_entity_form'][$ief_id]['entities']);
     if ($cardinality > 1) {
       // Add a visual cue of cardinality count.
       $message = t('You have added @entities_count out of @cardinality_count allowed @label.', array(
@@ -656,7 +678,7 @@ function inline_entity_form_field_widget_form(&$form, &$form_state, $field, $ins
       );
     }
     // Do not return the rest of the form if cardinality count has been reached.
-    if ($cardinality > 0 && $entity_count == $cardinality) {
+    if ($cardinality_reached) {
       return $element;
     }
 
@@ -769,6 +791,10 @@ function inline_entity_form_field_widget_form(&$form, &$form_state, $field, $ins
       elseif ($form_state['inline_entity_form'][$ief_id]['form'] == 'ief_add_existing') {
         $element['form'] += inline_entity_form_reference_form($controller, $element['form'], $form_state);
       }
+      elseif ($form_state['inline_entity_form'][$ief_id]['form'] == 'clone') {
+        $element['form']['#op'] = 'clone';
+        $element['form'] += inline_entity_form_entity_form($controller, $element['form'], $form_state);
+      }
 
       // No entities have been added. Remove the outer fieldset to reduce
       // visual noise caused by having two titles.
@@ -856,6 +882,14 @@ function inline_entity_form_entity_form($controller, $entity_form, &$form_state)
     $entity_form['#title'] = t('Add new @type_singular', array('@type_singular' => $labels['singular']));
     $save_label = t('Create @type_singular', array('@type_singular' => $labels['singular']));
   }
+  elseif ($entity_form['#op'] == 'clone') {
+    // Clone the entity.
+    $form_settings = $form_state['inline_entity_form'][$entity_form['#ief_id']]['form settings'];
+    $entity = $form_state['inline_entity_form'][$entity_form['#ief_id']]['entities'][$form_settings['source']]['entity'];
+    $entity_form['#entity'] = $controller->createClone($entity);
+    $entity_form['#title'] = t('Clone @type_singular', array('@type_singular' => $labels['singular']));
+    $save_label = t('Clone @type_singular', array('@type_singular' => $labels['singular']));
+  }
 
   // Retrieve the form provided by the controller.
   $entity_form = $controller->entityForm($entity_form, $form_state);
@@ -888,13 +922,13 @@ function inline_entity_form_entity_form($controller, $entity_form, &$form_state)
   );
 
   // Add the appropriate submit handlers and their related data.
-  if ($entity_form['#op'] == 'add') {
-    $entity_form['actions']['ief_add_save']['#submit'] = array(
+  if (in_array($entity_form['#op'], array('add', 'clone'))) {
+    $entity_form['actions']['ief_' . $entity_form['#op'] . '_save']['#submit'] = array(
       'inline_entity_form_trigger_submit',
       'inline_entity_form_close_child_forms',
       'inline_entity_form_close_form',
     );
-    $entity_form['actions']['ief_add_cancel']['#submit'] = array(
+    $entity_form['actions']['ief_' . $entity_form['#op'] . '_cancel']['#submit'] = array(
       'inline_entity_form_close_child_forms',
       'inline_entity_form_close_form',
       'inline_entity_form_cleanup_form_state',
@@ -976,7 +1010,7 @@ function inline_entity_form_entity_form_submit($entity_form, &$form_state) {
   $controller->entityFormSubmit($entity_form, $form_state);
   inline_entity_form_cleanup_entity_form_state($entity_form, $form_state);
 
-  if ($entity_form['#op'] == 'add') {
+  if (in_array($entity_form['#op'], array('add', 'clone'))) {
     // Determine the correct weight of the new element.
     $weight = 0;
     if (!empty($form_state['inline_entity_form'][$ief_id]['entities'])) {
@@ -1301,10 +1335,14 @@ function inline_entity_form_open_form($form, &$form_state) {
   $form_values = drupal_array_get_nested_value($form_state['values'], $parents);
 
   $form_state['inline_entity_form'][$ief_id]['form'] = $form_state['triggering_element']['#ief_form'];
+  $form_state['inline_entity_form'][$ief_id]['form settings'] = array();
+  // Special code for the add form.
   if (!empty($form_values['actions']['bundle'])) {
-    $form_state['inline_entity_form'][$ief_id]['form settings'] = array(
-      'bundle' => $form_values['actions']['bundle'],
-    );
+    $form_state['inline_entity_form'][$ief_id]['form settings']['bundle'] = $form_values['actions']['bundle'];
+  }
+  // Special code for the clone form.
+  if (isset($form_state['triggering_element']['#ief_row_delta'])) {
+    $form_state['inline_entity_form'][$ief_id]['form settings']['source'] = $form_state['triggering_element']['#ief_row_delta'];
   }
 }
 
