diff --git a/lib/keepalive.c b/lib/keepalive.c
index 366c51c..352b5db 100644
--- a/lib/keepalive.c
+++ b/lib/keepalive.c
@@ -738,6 +738,116 @@ ka_unixctl_status(struct unixctl_conn *conn, int argc OVS_UNUSED,
     ds_destroy(&ds);
 }
 
+static void
+ka_unixctl_pmd_xstats_show(struct unixctl_conn *conn, int argc OVS_UNUSED,
+                       const char *argv[] OVS_UNUSED, void *ka_info_)
+{
+    struct ds ds = DS_EMPTY_INITIALIZER;
+    ds_put_format(&ds,
+                  "\n\t\tKeepalive xstats\n\n");
+
+    ds_put_format(&ds, "keepalive status  : %s\n",
+                  ka_is_enabled() ? "Enabled" : "Disabled");
+
+    if (!ka_is_enabled()) {
+        goto out;
+    }
+
+    ds_put_format(&ds, "keepalive interval: %"PRIu32" ms\n",
+                  get_ka_interval());
+
+    struct keepalive_info *ka_info = (struct keepalive_info *)ka_info_;
+    if (!ka_info) {
+        goto out;
+    }
+
+    ds_put_format(&ds, "PMD threads       : %"PRIu32" \n", ka_info->pmd_cnt);
+
+    struct ka_process_info *pinfo, *pinfo_next;
+    ovs_mutex_lock(&ka_info->proclist_mutex);
+    HMAP_FOR_EACH_SAFE (pinfo, pinfo_next, node, &ka_info->process_list) {
+        char *state = NULL;
+        if (pinfo->core_state == KA_STATE_UNUSED ||
+             pinfo->core_state == KA_STATE_SLEEP)
+            continue;
+
+        switch (pinfo->core_state) {
+        case KA_STATE_ALIVE:
+            state = "ALIVE";
+            break;
+        case KA_STATE_MISSING:
+            state = "MISSING";
+            break;
+        case KA_STATE_DEAD:
+            state = "DEAD";
+            break;
+        case KA_STATE_GONE:
+            state = "GONE";
+            break;
+        case KA_STATE_DOZING:
+            state = "DOZING";
+            break;
+        case KA_STATE_SLEEP:
+            state = "SLEEP";
+            break;
+        case KA_STATE_CHECK:
+            state = "HEALTH_CHECK_RUNNING";
+            break;
+        case KA_STATE_UNUSED:
+            break;
+        }
+
+        ds_put_format(&ds, "\n");
+        ds_put_format(&ds, "  %s\n", pinfo->name);
+        ds_put_format(&ds, "\tPMD core_id         : %d\n", pinfo->core_id);
+        ds_put_format(&ds, "\tPMD thread-id       : %d [%s]\n",
+                     pinfo->tid, process_is_active(pinfo->tid) ?
+                     "ACTIVE" : "INACTIVE");
+        ds_put_format(&ds, "\tPMD heartbeats      : %s\n",
+                      ka_is_enabled() ? "enabled" : "disabled");
+        ds_put_format(&ds, "\tPMD state           : %s\n", state);
+        ds_put_format(&ds, "\tLast seen timestamp : %"PRIu64"\n",
+                      pinfo->core_last_seen_times);
+
+        ds_put_format(&ds, "\tPMD failure count   : %d\n",
+                      pinfo->failures);
+
+        int health_check = pinfo->healthcheck;
+        if (health_check) {
+            ds_put_format(&ds, "\tPMD health check    : %s\n",
+                      health_check ? "enabled" : "disabled");
+            ds_put_format(&ds, "\tPacket Stats\n");
+
+            int cid = pinfo->core_id;
+            int n = ka_info->ext_stats[cid].num_poll_ports;
+            for (int idx = 0; idx < n; idx++) {
+                    ds_put_format(&ds, "\t\tPort %s, Link status: %s\n",
+                        ka_info->ext_stats[cid].port_stats[idx].port,
+                        ka_info->ext_stats[cid].port_stats[idx].link_state);
+                    ds_put_format(&ds, "\t\trx_packets : %"PRIu64"\n",
+                                  ka_info->ext_stats[cid].  \
+                                  port_stats[idx].stats.rx_packets);
+                    ds_put_format(&ds, "\t\ttx_packets : %"PRIu64"\n",
+                                  ka_info->ext_stats[cid].port_stats[idx]. \
+                                  stats.tx_packets);
+            }
+
+            ds_put_format(&ds, "\tCycle Stats\n");
+
+            ds_put_format(&ds, "\t\tPolling cycles : %"PRIu64"\n",
+                ka_info->ext_stats[cid].cycles[PMD_CYCLES_IDLE]);
+            ds_put_format(&ds, "\t\tProcessing cycles : %"PRIu64"\n",
+                ka_info->ext_stats[cid].cycles[PMD_CYCLES_PROCESSING]);
+        }
+    }
+    ovs_mutex_unlock(&ka_info->proclist_mutex);
+
+    ds_put_format(&ds, "\n");
+out:
+    unixctl_command_reply(conn, ds_cstr(&ds));
+    ds_destroy(&ds);
+}
+
 static int
 ka_init__(void)
 {
@@ -784,6 +894,8 @@ ka_init(const struct smap *ovs_other_config)
                                   ka_unixctl_pmd_health_show, ka_info);
         unixctl_command_register("keepalive/status", "", 0, 0,
                                       ka_unixctl_status, NULL);
+        unixctl_command_register("keepalive/pmd-xstats-show", "", 0, 0,
+                                      ka_unixctl_pmd_xstats_show, ka_info);
 
         ovsthread_once_done(&once_enable);
     }
