diff --git a/location.info b/location.info
index a978854..d6dba91 100644
--- a/location.info
+++ b/location.info
@@ -8,6 +8,7 @@ files[] = location.install
 files[] = location.admin.inc
 files[] = location.georss.inc
 files[] = location.inc
+files[] = location.migrate.inc
 files[] = location.token.inc
 files[] = location.views.inc
 files[] = location.views_default.inc
diff --git a/location.migrate.inc b/location.migrate.inc
new file mode 100644
index 0000000..79db38a
--- /dev/null
+++ b/location.migrate.inc
@@ -0,0 +1,105 @@
+<?php
+/**
+ * Primary value passed to this field is the is_primary value (boolean)
+ * but can be overwritten with subfields.
+ *
+ * Subfields are used to specify all the other values:
+ *  'street'
+ *  'additional',
+ *  'city',
+ *  'province',
+ *  'postal_code',
+ *  'country',
+ *  'is_primary',
+ *  'latitude',
+ *  'longitude'
+ *
+ * @code
+ *   $this->addFieldMapping('field_location_dest')->defaultValue('TRUE');
+ *   $this->addFieldMapping('field_location_dest:street', 'field_source_address_1');
+ *   $this->addFieldMapping('field_location_dest:city', 'field_source_city');
+ * @endcode
+ */
+class MigrateLocationFieldHandler extends MigrateFieldHandler {
+
+  public function __construct() {
+    $this->registerTypes(array('location'));
+  }
+
+  /**
+   * Implementation of MigrateFieldHandler::fields().
+   *
+   * @param $type
+   *  The file field type - 'file' or 'image'
+   * @param $parent_field
+   *  Name of the parent field.
+   * @param Migration $migration
+   *  The migration context for the parent field. We can look at the mappings
+   *  and determine which subfields are relevant.
+   * @return array
+   */
+  public function fields($type, $parent_field, $migration = NULL) {
+
+    $fields = parent::fields($type, $parent_field, $migration);
+    $fields += array(
+      'name'        => t('Subfield: String to be used as the name value'),
+      'street'      => t('Subfield: String to be used as the street value'),
+      'additional'  => t('Subfield: String to be used as the additional value'),
+      'city'        => t('Subfield: String to be used as the city value'),
+      'province'    => t('Subfield: String to be used as the province value'),
+      'postal_code' => t('Subfield: String to be used as the postal code value'),
+      'latitude'    => t('Subfield: Float to be used as the latitude value'),
+      'longitude'   => t('Subfield: Float to be used as the longitude value'),
+      'country'     => t('Subfield: String (ISO code) to be used as the country value'),
+      'source'      => t('Subfield: String to be used as the source value'),
+      'is_primary'  => t('Subfield: Boolean to be used as the is primary value'),
+    );
+    return $fields;
+  }
+
+  public function prepare($entity, array $field_info, array $instance, array $values) {
+
+    $migration   = Migration::currentMigration();
+    $destination = $migration->getDestination();
+
+    $arguments = array();
+    if (isset($values['arguments'])) {
+      $arguments = $values['arguments'];
+      unset($values['arguments']);
+    }
+    $language = $this->getFieldLanguage($entity, $field_info, $arguments);
+
+    // For each location...
+    $delta = 0;
+    $return = array($language => array());
+    foreach ($values as $value) {
+
+      // Build the address and save it as a location
+      $location_fields = array('name', 'street', 'additional', 'city', 'province', 'postal_code', 'latitude', 'longitiude', 'country', 'source', 'is_primary',);
+      $address = array();
+      $address['is_primary'] = (bool) $value;
+      foreach ($location_fields as $location_field) {
+        if (isset($arguments[$location_field])) {
+          $address[$location_field] = $location_field == 'country'
+          ? strtolower($arguments[$location_field][0]->value)
+            : $arguments[$location_field][0]->value;
+        }
+      }
+      $lid = location_save($address);
+
+      // If the location was saved successfully, store the created lid in the location field
+      if ($lid) {
+        $field_name = $instance['field_name'];
+        $field_row = array(
+          'lid' => $lid,
+        );
+        $return[$language][$delta] = $field_row;
+      }
+      $delta++;
+    }
+
+    return $return;
+
+  }
+
+}
\ No newline at end of file
diff --git a/location.module b/location.module
index 69ed70a..6316362 100644
--- a/location.module
+++ b/location.module
@@ -156,6 +156,17 @@ function location_element_info() {
 }
 
 /**
+ * Implements hook_migrate_api().
+ */
+function location_migrate_api() {
+  $api = array(
+    'api' => 2,
+  );
+
+  return $api;
+}
+
+/**
  * Theme function to fixup location elements.
  * @ingroup themable
  */
@@ -303,7 +314,7 @@ function _location_process_location($element, $form_state) {
         $element[$field]['#weight'] = (int) $fsettings[$field]['weight'];
       }
     }
-    
+
     // If State/Province is using the select widget, update the element's options.
     if ($field == 'province' && $fsettings[$field]['widget'] == 'select') {
       // We are building the element for the first time
@@ -443,7 +454,7 @@ function _location_process_location($element, $form_state) {
   }
 
   $element += element_info('fieldset');
-  
+
   drupal_alter('location_element', $element);
   return $element;
 }
@@ -500,7 +511,7 @@ function _location_process_location_settings(&$element) {
       '#default_value' => $defaults[$field]['collect'],
       '#options' => $options,
     );
-    
+
     $dummy = array();
     $widgets = location_invoke_locationapi($dummy, 'widget', $field);
     if (!empty($widgets)) {
@@ -510,7 +521,7 @@ function _location_process_location_settings(&$element) {
         '#options' => $widgets,
       );
     }
-    
+
     $temp = $defaults[$field]['default'];
     $element[$field]['default'] = location_invoke_locationapi($temp, 'field_expand', $field, 1, $defaults);
     $defaults[$field]['default'] = $temp;
@@ -557,7 +568,7 @@ function theme_location_settings($variables) {
     $row[] = array('data' => '', 'class' => array('location-settings-drag'));
     $row[] = drupal_render($element[$key]['name']);
     $row[] = drupal_render($element[$key]['collect']);
-    $row[] = !empty($element[$key]['widget']) ? drupal_render($element[$key]['widget']) : ''; 
+    $row[] = !empty($element[$key]['widget']) ? drupal_render($element[$key]['widget']) : '';
     $row[] = drupal_render($element[$key]['default']);
     $row[] = array('data' => drupal_render($element[$key]['weight']), 'class' => array('delta-order'));
 
@@ -659,8 +670,8 @@ function location_locationapi(&$obj, $op, $a3 = NULL, $a4 = NULL, $a5 = NULL) {
           }
         }
       }
-      
-      
+
+
 
       if (!empty($obj['locpick']) && is_array($obj['locpick'])) {
         // Can't specify just latitude or just longitude.
@@ -1086,7 +1097,7 @@ function _location_autocomplete($country, $string = '') {
 }
 
 /**
- * AJAX callback for the Country select form, for cases where the province list  
+ * AJAX callback for the Country select form, for cases where the province list
  * is also a select element and its options need to be updated. Uses the D7 Ajax
  * Framework to do the select list updating.
  *
@@ -1104,7 +1115,7 @@ function _location_country_ajax_callback($form, $form_state) {
     return $form['locations'][arg(3)]['province'];
   }
   elseif (isset($form[arg(2)][arg(3)][arg(4)])) {
-    return $form[arg(2)][arg(3)][arg(4)]['province']; 
+    return $form[arg(2)][arg(3)][arg(4)]['province'];
   }
 }
 
@@ -1520,8 +1531,8 @@ function _location_geo_logic(&$location, $changed, $filled, $inhibit_geocode = F
   // collected through the form, set them to whatever the postal code data
   // says they should be.
   if (!empty($location['postal_code'])) {
-    if (  empty($location['city']) || 
-          empty($location['province']) || 
+    if (  empty($location['city']) ||
+          empty($location['province']) ||
           empty($location['location_settings']['form']['fields']['city']['collect']) ||
           empty($location['location_settings']['form']['fields']['province']['collect'])
        ) {
@@ -1646,7 +1657,7 @@ function template_preprocess_location(&$variables) {
   // Map link.
   $variables['map_link'] = '';
   if (!empty($location['map_link'])) {
-    // Do not use $location for generating the map link, since it will 
+    // Do not use $location for generating the map link, since it will
     // not contain the country if that field is hidden.
     $variables['map_link'] = location_map_link($variables['location']);
   }
