diff --git a/rb_batch/rb_batch.inc b/rb_batch/rb_batch.inc
index 19516de..afd41d8 100644
--- a/rb_batch/rb_batch.inc
+++ b/rb_batch/rb_batch.inc
@@ -82,3 +82,90 @@ function rb_batch_action_batch_context($message, $finished) {
    * @see rb_batch.module
    */
 }
+
+
+/**
+ * A batched loop element.
+ */
+class RulesBatchLoop extends RulesLoop {
+
+  protected $itemName = 'batch_loop';
+  protected $listItemInfo;
+
+  public function evaluate(RulesState $state) {
+    try {
+      $param_info = $this->pluginParameterInfo();
+      $list = $this->getArgument('list', $param_info['list'], $state);
+      $item_var_info = $this->listItemInfo();
+      $item_var_name = $this->settings['item:var'];
+
+      if (isset($this->settings['list:select'])) {
+        rules_log('Looping over the list items of %selector', array('%selector' => $this->settings['list:select']), RulesLog::INFO, $this);
+      }
+
+      $batch = array(
+        'operations' => array(),
+        'finished' => 'rb_batch_loop_finished',
+        'file' => drupal_get_path('module', 'rb_batch') . '/rb_batch.inc',
+      );
+
+      // Loop over the list and set a batch operation for each list item.
+      foreach ($list as $key => $item) {
+        // Use a separate state so variables are available in the loop only.
+        $state2 = clone $state;
+        $state2->addVariable($item_var_name, $list[$key], $item_var_info);
+
+        $batch['operations'][] = array(
+          'rb_batch_loop_op',
+          array($this, $state2),
+        );
+      }
+      batch_set($batch);
+    }
+    catch (RulesEvaluationException $e) {
+      rules_log($e->msg, $e->args, $e->severity);
+      rules_log('Unable to evaluate %name.', array('%name' => $this->getPluginName()), RulesLog::WARN, $this);
+    }
+  }
+
+  /**
+   * Evaluate a single batch item.
+   *
+   * @param RulesState
+   *   the state populated with the list item from the batch loop.
+   */
+  public function evaluate_single(RulesState $state) {
+    foreach ($this->children as $action) {
+      $action->evaluate($state);
+    }
+  }
+
+  public function label() {
+    return !empty($this->label) ? $this->label : t('Batch Loop');
+  }
+}
+
+/**
+ * Batch operation for calling a rule.
+ *
+ * @param RulesBatchLoop $plugin
+ * @param RulesState $state
+ * @param $context
+ *   array of batch context
+ */
+function rb_batch_loop_op($plugin, $state, &$context) {
+
+  $plugin->evaluate_single($state);
+
+  // @TODO: get a message text via action:
+  // $context['message'] = check_plain($title);
+  // @TODO: get result text via action:
+  // $context['results'][] = t('Updated contentqueue cache for component @title (nid:@nid)', array('@nid' => $nid, '@title' => $title));
+}
+
+
+/**
+ * Finish callback.
+ */
+function rb_batch_loop_finished($success, $results, $operations) {
+}
diff --git a/rb_batch/rb_batch.module b/rb_batch/rb_batch.module
index 73e8880..af77205 100644
--- a/rb_batch/rb_batch.module
+++ b/rb_batch/rb_batch.module
@@ -26,6 +26,15 @@ function rb_batch_rules_plugin_info() {
         ),
       ),
     ),
+    'batch_loop' => array(
+      'class' => 'RulesBatchLoop',
+      'embeddable' => 'RulesActionContainer',
+      'extenders' => array(
+        'RulesPluginUIInterface' => array(
+          'class' => 'RulesLoopUI',
+        ),
+      ),
+    ),
   );
 }
 
