diff --git a/circle/dashboard/static/dashboard/vm-list.js b/circle/dashboard/static/dashboard/vm-list.js
index 35d7ea6..2df8867 100644
--- a/circle/dashboard/static/dashboard/vm-list.js
+++ b/circle/dashboard/static/dashboard/vm-list.js
@@ -114,7 +114,7 @@ $(function() {
 
   $("body").on("click", "#op-form-send", function() {
     var url = $(this).closest("form").prop("action");
-    $(this).find("i").prop("class", "fa fa-spinner fa-spin");
+    $(this).find("i").prop("class", "fa fa-fw fa-spinner fa-spin");
 
     $.ajax({
       url: url,
@@ -177,7 +177,8 @@ $(function() {
 
 
 function checkStatusUpdate() {
-  if($("#vm-list-table tbody td.state i").hasClass("fa-spin")) {
+  icons = $("#vm-list-table tbody td.state i");
+  if(icons.hasClass("fa-spin") || icons.hasClass("migrating-icon")) {
     return true;
   }
 }
@@ -194,12 +195,20 @@ function updateStatuses(runs) {
       if(vm in result) {
         if(result[vm].in_status_change) {
           if(!status_icon.hasClass("fa-spin")) {
-            status_icon.prop("class", "fa fa-spinner fa-spin");
+            status_icon.prop("class", "fa fa-fw fa-spinner fa-spin");
+          }
+        }
+        else if(result[vm].status == "MIGRATING") {
+          if(!status_icon.hasClass("migrating-icon")) {
+            status_icon.prop("class", "fa fa-fw " + result[vm].icon + " migrating-icon");
           }
         } else {
-          status_icon.prop("class", "fa " + result[vm].icon);
+          status_icon.prop("class", "fa fa-fw " + result[vm].icon);
         }
         status_text.text(result[vm].status);
+        if("node" in result[vm]) {
+          $(this).find(".node").text(result[vm].node);
+        }
       } else {
         $(this).remove();
       }
diff --git a/circle/dashboard/templates/dashboard/_vm-mass-migrate.html b/circle/dashboard/templates/dashboard/_vm-mass-migrate.html
new file mode 100644
index 0000000..2b3125b
--- /dev/null
+++ b/circle/dashboard/templates/dashboard/_vm-mass-migrate.html
@@ -0,0 +1,29 @@
+{% extends "dashboard/mass-operate.html" %}
+{% load i18n %}
+{% load sizefieldtags %}
+
+{% block question %}
+<p>
+{% blocktrans with op=op.name %}
+Choose a compute node to migrate the selected VMs to.
+{% endblocktrans %}
+</p>
+<p class="text-info">{{op.name}}: {{op.description}}</p>
+{% endblock %}
+
+{% block formfields %}
+  <ul id="vm-migrate-node-list" class="list-unstyled">
+    {% for n in nodes %}
+      <li class="panel panel-default"><div class="panel-body">
+        <label for="migrate-to-{{n.pk}}">
+          <strong>{{ n }}</strong>
+        </label>
+        <input id="migrate-to-{{n.pk}}" type="radio" name="node" value="{{ n.pk }}" style="float: right;" checked="checked">
+        <span class="vm-migrate-node-property">{% trans "CPU load" %}: {{ n.cpu_usage }}</span>
+        <span class="vm-migrate-node-property">{% trans "RAM usage" %}: {{ n.byte_ram_usage|filesize }}/{{ n.ram_size|filesize }}</span>
+        <div style="clear: both;"></div>
+      </div></li>
+    {% endfor %}
+  </ul>
+  <hr />
+{% endblock %}
diff --git a/circle/dashboard/templates/dashboard/mass-operate.html b/circle/dashboard/templates/dashboard/mass-operate.html
index 7306fd1..f43092c 100644
--- a/circle/dashboard/templates/dashboard/mass-operate.html
+++ b/circle/dashboard/templates/dashboard/mass-operate.html
@@ -10,26 +10,27 @@ Do you want to perform the following operation: <strong>{{op}}</strong>?
 <p class="text-info">{{op.description}}</p>
 {% endblock %}
 <form method="POST" action="{{url}}">{% csrf_token %}
-    {% for i in instances %}
-    <div class="panel panel-default mass-op-panel">
-      <i class="fa {{ i.get_status_icon }} fa-fw"></i>
-      {{ i.name }} ({{ i.pk }})
-      <div style="float: right;" title="{{ i.disabled }}">
-        <i class="fa status-icon
-          {% if i.disabled %}fa-minus-square minus{% else %}fa-check-square check{% endif %}">
-        </i>
-      </div>
+  {% block formfields %}{% endblock %}
+  {% for i in instances %}
+  <div class="panel panel-default mass-op-panel">
+    <i class="fa {{ i.get_status_icon }} fa-fw"></i>
+    {{ i.name }} ({{ i.pk }})
+    <div style="float: right;" title="{{ i.disabled }}">
+      <i class="fa status-icon
+        {% if i.disabled %}fa-minus-square minus{% else %}fa-check-square check{% endif %}">
+      </i>
     </div>
-    <input type="checkbox" name="vm" value="{{ i.pk }}" {% if not i.disabled %}checked{% endif %}
-      style="display: none;"/>
-    {% endfor %}
+  </div>
+  <input type="checkbox" name="vm" value="{{ i.pk }}" {% if not i.disabled %}checked{% endif %}
+    style="display: none;"/>
+  {% endfor %}
 
   <div class="pull-right">
     <a class="btn btn-default" href="{% url "dashboard.views.vm-list" %}"
-        data-dismiss="modal">{% trans "Cancel" %}</a>
+     data-dismiss="modal">{% trans "Cancel" %}</a>
     <button class="btn btn-{{ opview.effect }}" type="submit" id="op-form-send">
-        {% if opview.icon %}<i class="fa fa-{{opview.icon}}"></i> {% endif %}{{ opview.name|capfirst }}
-      </button>
+      {% if opview.icon %}<i class="fa fa-fw fa-{{opview.icon}}"></i> {% endif %}{{ opview.name|capfirst }}
+    </button>
   </div>
 </form>
 
diff --git a/circle/dashboard/templates/dashboard/vm-list.html b/circle/dashboard/templates/dashboard/vm-list.html
index f56055c..60d314c 100644
--- a/circle/dashboard/templates/dashboard/vm-list.html
+++ b/circle/dashboard/templates/dashboard/vm-list.html
@@ -66,7 +66,7 @@
             <td class="pk"><div id="vm-{{i.pk}}">{{i.pk}}</div> </td>
             <td class="name"><a class="real-link" href="{% url "dashboard.views.detail" i.pk %}">{{ i.name }}</a>  </td>
             <td class="state">
-              <i class="fa 
+              <i class="fa fa-fw
                 {% if i.is_in_status_change %}
                   fa-spin fa-spinner
                 {% else %}
@@ -77,7 +77,9 @@
               {% include "dashboard/_display-name.html" with user=i.owner show_org=True %}
             </td>
             {% if user.is_superuser %}
-            <td data-sort-value="{{ i.node.normalized_name }}">{{ i.node.name|default:"-" }}</td>
+            <td class="node "data-sort-value="{{ i.node.normalized_name }}">
+              {{ i.node.name|default:"-" }}
+            </td>
             {% endif %}
           </tr>
           {% empty %}
@@ -109,4 +111,53 @@
 {% block extra_js %}
   <script src="{{ STATIC_URL}}dashboard/vm-list.js"></script>
   <script src="{{ STATIC_URL}}dashboard/js/stupidtable.min.js"></script>
+  <style>
+    #vm-list-table .migrating-icon {
+      -webkit-animation: passing 2s linear infinite;
+      animation: passing 2s linear infinite;
+    }
+
+@-webkit-keyframes passing {
+  0% {
+    -webkit-transform: translateX(50%);
+    transform: translateX(50%);
+    opacity: 0;
+  }
+
+  50% {
+    -webkit-transform: translateX(0%);
+    transform: translateX(0%);
+    opacity: 1;
+  }
+
+  100% {
+    -webkit-transform: translateX(-50%);
+    transform: translateX(-50%);
+    opacity: 0;
+  }
+}
+
+@keyframes passing {
+  0% {
+    -webkit-transform: translateX(50%);
+    -ms-transform: translateX(50%);
+    transform: translateX(50%);
+    opacity: 0;
+  }
+
+  50% {
+    -webkit-transform: translateX(0%);
+    -ms-transform: translateX(0%);
+    transform: translateX(0%);
+    opacity: 1;
+  }
+
+  100% {
+    -webkit-transform: translateX(-50%);
+    -ms-transform: translateX(-50%);
+    transform: translateX(-50%);
+    opacity: 0;
+  }
+}
+  </style>
 {% endblock %}
diff --git a/circle/dashboard/views.py b/circle/dashboard/views.py
index 2bf4e0d..71a576e 100644
--- a/circle/dashboard/views.py
+++ b/circle/dashboard/views.py
@@ -1034,14 +1034,16 @@ class MassOperationView(OperationView):
             vms.append(i)
         return vms
 
-    def post(self, request, *args, **kwargs):
+    def post(self, request, extra=None, *args, **kwargs):
+        if extra is None:
+            extra = {}
         user = self.request.user
         vms = request.POST.getlist("vm")
         instances = Instance.objects.filter(pk__in=vms)
         for i in instances:
             try:
                 op = self._op_checks(i, user)
-                op.async(user=user)
+                op.async(user=user, **extra)
             except HumanReadableException as e:
                 e.send_message(request)
             except Exception as e:
@@ -1067,6 +1069,28 @@ class MassOperationView(OperationView):
         return op
 
 
+class MassMigrationView(MassOperationView):
+    template_name = 'dashboard/_vm-mass-migrate.html'
+    icon = "info"
+    op = "migrate"
+    icon = "truck"
+
+    def get_context_data(self, **kwargs):
+        ctx = super(MassMigrationView, self).get_context_data(**kwargs)
+        ctx['nodes'] = [n for n in Node.objects.filter(enabled=True)
+                        if n.state == "ONLINE"]
+        return ctx
+
+    def post(self, request, extra=None, *args, **kwargs):
+        if extra is None:
+            extra = {}
+        node = self.request.POST.get("node")
+        if node:
+            node = get_object_or_404(Node, pk=node)
+            extra["to_node"] = node
+        return super(MassMigrationView, self).post(request, extra, *args,
+                                                   **kwargs)
+
 vm_mass_ops = OrderedDict([
     ('deploy', MassOperationView.factory(
         op='deploy', icon='play', effect='success')),
@@ -1074,6 +1098,7 @@ vm_mass_ops = OrderedDict([
         op='wake_up', icon='sun-o', effect='success')),
     ('sleep', MassOperationView.factory(
         op='sleep', icon='moon-o', effect='info')),
+    ('migrate', MassMigrationView),
     ('destroy', MassOperationView.factory(
         op='destroy', icon='times', effect='danger')),
 ])
@@ -1671,6 +1696,8 @@ class VmList(LoginRequiredMixin, FilterMixin, ListView):
                     'icon': i.get_status_icon(),
                     'in_status_change': i.is_in_status_change(),
                 }
+                if self.request.user.is_superuser:
+                    statuses[i.pk]['node'] = i.node.name if i.node else "-"
             return HttpResponse(json.dumps(statuses),
                                 content_type="application/json")
         else:
diff --git a/circle/vm/models/instance.py b/circle/vm/models/instance.py
index 8ad4ad6..3c552f7 100644
--- a/circle/vm/models/instance.py
+++ b/circle/vm/models/instance.py
@@ -938,7 +938,8 @@ class Instance(AclBase, VirtualMachineDescModel, StatusModel, OperatedMixin,
             'ERROR': 'fa-warning',
             'PENDING': 'fa-rocket',
             'DESTROYED': 'fa-trash-o',
-            'MIGRATING': 'fa-truck'}.get(self.status, 'fa-question')
+            'MIGRATING': 'fa-truck migrating-icon'
+        }.get(self.status, 'fa-question')
 
     def get_activities(self, user=None):
         acts = (self.activity_log.filter(parent=None).