diff --git a/commerce_ipf.module b/commerce_ipf.module
index 19ec55d..d440499 100644
--- a/commerce_ipf.module
+++ b/commerce_ipf.module
@@ -83,7 +83,8 @@ function commerce_ipf_field_widget_form(&$form, &$form_state, $field, $instance,
       }
 
       $delta = 0;
-      foreach (entity_load('commerce_product', $product_ids) as $product) {
+      $products = entity_load('commerce_product', $product_ids);
+      foreach ($products as $product) {
         $form_state['commerce_ipf'][$parents_key]['products'][$delta] = array(
           'data' => $product,
           'weight' => $delta,
@@ -105,8 +106,13 @@ function commerce_ipf_field_widget_form(&$form, &$form_state, $field, $instance,
       }
     }
 
+    // Include the IPF callbacks.
+    module_load_include('inc', 'commerce_ipf', 'includes/commerce_product.forms');
+
     // Loop over all the product data in the form state.
     $element['products'] = array('#tree' => TRUE, '#theme' => 'commerce_ipf_product_table');
+    $product_table = commerce_ipf_commerce_product_build_table($products);
+    $element['products']['#table_header'] = $product_table['#header'];
 
     foreach ($form_state['commerce_ipf'][$parents_key]['products'] as $key => $value) {
       $product = $value['data'];
@@ -130,10 +136,9 @@ function commerce_ipf_field_widget_form(&$form, &$form_state, $field, $instance,
           '#type' => 'container',
           '#weight' => 100,
         );
-        // Prepare data for the form callbacks and include the parent file.
+        // Prepare data for the form callbacks.
         $form = &$element['products'][$key]['form'];
         $form_parents = array_merge($parents, array('products', $key, 'form'));
-        module_load_include('inc', 'commerce_ipf', 'includes/commerce_product.forms');
 
         // Add the product add / edit form.
         if ($value['form'] == 'add' || $value['form'] == 'edit') {
@@ -192,15 +197,7 @@ function commerce_ipf_field_widget_form(&$form, &$form_state, $field, $instance,
       else {
         // Otherwise add the product data for the table row.
         $row = &$element['products'][$key];
-        $row['title'] = array(
-          '#markup' => check_plain($product->title),
-          '#attributes' => array('class' => array('commerce-ipf-product-title')),
-        );
-
-        $row['sku'] = array(
-          '#markup' => check_plain($product->sku),
-          '#attributes' => array('class' => array('commerce-ipf-product-sku')),
-        );
+        $row['#table_row'] = $product_table['#rows'][$key];
 
         // Add an actions container with edit and delete buttons for the product.
         $row['actions'] = array(
@@ -452,18 +449,18 @@ function commerce_ipf_widget_refresh($form, $form_state) {
  *   Contains the form element data from $element['products'].
  */
 function theme_commerce_ipf_product_table($variables) {
+  $form = $variables['form'];
+
   $header = array(
     array('data' => '', 'class' => array('ipf-tabledrag-header')),
     array('data' => t('Sort order'), 'class' => array('ipf-sort-order-header')),
-    array('data' => t('Product title'), 'class' => array('ipf-product-header')),
-    t('SKU'),
-    t('Operations'),
   );
+  // Add headers provided by the IPF table callback.
+  $header = array_merge($header, $form['#table_header']);
+  $header[] = t('Operations');
 
   // Build an array of product rows for the table.
-  $form = $variables['form'];
   $rows = array();
-
   foreach (element_children($form) as $key) {
     // If the current product array specifies a form, output that in a multi-
     // column cell in the table.
@@ -479,10 +476,10 @@ function theme_commerce_ipf_product_table($variables) {
       $row = array(
         array('data' => '', 'class' => array('ipf-tabledrag-handle')),
         drupal_render($form[$key]['delta']),
-        drupal_render($form[$key]['title']),
-        drupal_render($form[$key]['sku']),
-        drupal_render($form[$key]['actions']),
       );
+      // Add cells provided by the IPF table callback.
+      $row = array_merge($row, $form[$key]['#table_row']);
+      $row[] = drupal_render($form[$key]['actions']);
     }
 
     $rows[] = array('data' => $row, 'class' => array('draggable'));
diff --git a/includes/commerce_product.forms.inc b/includes/commerce_product.forms.inc
index 45f6bbb..eba61e4 100644
--- a/includes/commerce_product.forms.inc
+++ b/includes/commerce_product.forms.inc
@@ -6,6 +6,27 @@
  */
 
 /**
+ * IPF table callback: Returns the table used to identify existing products.
+ * Additional elements (weight, actions) are appended to this table later on.
+ */
+function commerce_ipf_commerce_product_build_table($products) {
+  $table['#header'] = array(
+    array('data' => t('Product title'), 'class' => array('ipf-product-header')),
+    array('data' => t('SKU')),
+  );
+
+  $table['#rows'] = array();
+  foreach ($products as $product) {
+    $table['#rows'][] = array(
+      array('data' => check_plain($product->title), 'class' => array('commerce-ipf-product-title')),
+      array('data' => check_plain($product->sku), 'class' => array('commerce-ipf-product-sku')),
+    );
+  }
+
+  return $table;
+}
+
+/**
  * IPF add/edit form callback: Returns the product form to be embedded.
  *
  * When adding data to $form_state it should be noted that there can be several
