diff --git a/lib/ofp-util.c b/lib/ofp-util.c
index adb87eb..f0c96db 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -3289,6 +3289,12 @@ ofputil_encode_aggregate_stats_reply(
     enum ofpraw raw;
 
     ofpraw_decode(&raw, request);
+    if (raw == OFPRAW_OFPST15_OXS_AGGREGATE_REQUEST) {
+        enum ofp_version version = request->version;
+
+        msg = ofpraw_alloc_stats_reply(request, 0);
+        oxs_put_agg_stat(msg, stats, version);
+    } else {
     if (raw == OFPRAW_OFPST10_AGGREGATE_REQUEST) {
         packet_count = unknown_to_zero(stats->packet_count);
         byte_count = unknown_to_zero(stats->byte_count);
@@ -3302,6 +3308,7 @@ ofputil_encode_aggregate_stats_reply(
     put_32aligned_be64(&asr->packet_count, htonll(packet_count));
     put_32aligned_be64(&asr->byte_count, htonll(byte_count));
     asr->flow_count = htonl(stats->flow_count);
+    }
 
     return msg;
 }
@@ -3311,12 +3318,21 @@ ofputil_decode_aggregate_stats_reply(struct ofputil_aggregate_stats *stats,
                                      const struct ofp_header *reply)
 {
     struct ofpbuf msg = ofpbuf_const_initializer(reply, ntohs(reply->length));
-    ofpraw_pull_assert(&msg);
+    enum ofperr error;
+    enum ofpraw raw;
 
+    raw = ofpraw_pull_assert(&msg);
+    if (raw == OFPRAW_OFPST15_OXS_AGGREGATE_REPLY) {
+        memset(stats, 0, sizeof (*stats));
+        error = oxs_pull_agg_stat(msg, stats);
+        if (error)
+            return error;
+    } else {
     struct ofp_aggregate_stats_reply *asr = msg.msg;
     stats->packet_count = ntohll(get_32aligned_be64(&asr->packet_count));
     stats->byte_count = ntohll(get_32aligned_be64(&asr->byte_count));
     stats->flow_count = ntohl(asr->flow_count);
+    }
 
     return 0;
 }
diff --git a/lib/ox-stat.c b/lib/ox-stat.c
index 8bea083..4cfcff7 100644
--- a/lib/ox-stat.c
+++ b/lib/ox-stat.c
@@ -148,11 +148,15 @@ static enum ofperr oxs_pull_match_entry(struct ofpbuf *b,
 static enum ofperr oxs_pull_raw(const uint8_t *, unsigned int ,
                                 struct ofputil_flow_stats *fs,
                                 ovs_be64 * cookie, ovs_be64 * cookie_mask);
+static enum ofperr oxs_pull_agg_raw(const uint8_t * p, unsigned int stat_len,
+                                    struct ofputil_aggregate_stats *fs);
 static void oxs_init(void);
 static void oxs_put_header__(struct ofpbuf *b, uint64_t header);
 static void oxs_put_header_len(struct ofpbuf *b,
                                enum oxs_ofb_stat_fields field,
                                enum ofp_version version);
+static int ox_put_agg_raw(struct ofpbuf *b, enum ofp_version oxs,
+                          const struct ofputil_aggregate_stats *fs);
 
 static bool
 is_experimenter_oxs(uint64_t header)
@@ -400,6 +404,87 @@ oxs_pull_stat(struct ofpbuf *b, struct ofputil_flow_stats *fs,
                         NULL);
 }
 
+static enum ofperr
+oxs_pull_agg_raw(const uint8_t * p, unsigned int stat_len,
+                 struct ofputil_aggregate_stats *fs)
+{
+    struct ofpbuf b = ofpbuf_const_initializer(p, stat_len);
+
+    while (b.size) {
+
+        uint64_t header;
+        unsigned int payload_len;
+        const struct oxs_field *field;
+        const uint8_t *payload;
+
+        oxs_pull_header__(&b, &header, &field);
+        payload_len = oxs_payload_len(header);
+        payload = ofpbuf_try_pull(&b, payload_len);
+
+        if (fs && field) {
+            switch (field->id) {
+            case OFPXST_OFB_FLOW_COUNT:
+                {
+                    uint32_t flow_count = 0;
+
+                    memcpy(&flow_count, payload, sizeof (flow_count));
+                    fs->flow_count = ntohl(flow_count);
+                }
+                break;
+            case OFPXST_OFB_PACKET_COUNT:
+                {
+                    uint64_t packet_count;
+
+                    memcpy(&packet_count, payload, sizeof (packet_count));
+                    fs->packet_count = ntohll(packet_count);
+                }
+                break;
+            case OFPXST_OFB_BYTE_COUNT:
+                {
+                    uint64_t byte_count;
+
+                    memcpy(&byte_count, payload, sizeof (byte_count));
+                    fs->byte_count = ntohll(byte_count);
+                }
+                break;
+            case OFPXST_OFB_DURATION:
+            case OFPXST_OFB_IDLE_TIME:
+                break;
+            }
+
+        }
+
+    }
+    return 0;
+}
+
+/* Retrieve struct ofp_oxs_stat from 'b', followed by the aggregate flow entry
+ * statistics in OXS format.
+ *
+ * Returns error if message parsing fails, otherwise returns zero . */
+int
+oxs_pull_agg_stat(struct ofpbuf b, struct ofputil_aggregate_stats *fs)
+{
+    struct ofp_oxs_stat *oxs = b.data;
+    uint8_t *p;
+    uint16_t stat_len;
+
+    stat_len = ntohs(oxs->length);
+
+    if (stat_len < sizeof *oxs) {
+        return OFPERR_OFPBMC_BAD_LEN;
+    }
+
+    p = ofpbuf_try_pull(&b, ROUND_UP(stat_len, 8));
+    if (!p) {
+        VLOG_DBG_RL(&rl, "oxs length %u, rounded up to a "
+                    "multiple of 8, is longer than space in message (max "
+                    "length %" PRIu32 ")", stat_len, b.size);
+        return OFPERR_OFPBMC_BAD_LEN;
+    }
+
+    return oxs_pull_agg_raw(p + sizeof *oxs, stat_len - sizeof *oxs, fs);
+ }
 static struct hmap oxs_header_map;
 static struct hmap oxs_name_map;
 
@@ -599,3 +684,84 @@ oxs_put_stat(struct ofpbuf *b, const struct ofputil_flow_stats *fs,
     return stat_len;
 }
 
+/* Appends to 'b' the aggregate flow entry statistics in a flexible encoding,
+ * OXS format.
+ *
+ * OXS is a TLV format to express flow entry statistics.  Specify the OpenFlow
+ * version in use as 'version'.
+ *
+ * Returns the number of bytes appended to 'b'.
+ *
+ * This function can cause 'b''s data to be reallocated.
+ *
+ * Returns zero or the number of bytes appended to 'b'. */
+static int
+ox_put_agg_raw(struct ofpbuf *b, enum ofp_version oxs,
+               const struct ofputil_aggregate_stats *fs)
+{
+   const size_t start_len = b->size;
+   int stat_len;
+
+   if (oxs_field_set & 1<<2) {
+     uint32_t flow_count = 0;
+     if(fs) {
+       flow_count=fs->flow_count;
+       flow_count=htonl(flow_count);
+     }
+     oxs_put__(b, OFPXST_OFB_FLOW_COUNT, oxs, &flow_count,
+                NULL, OXS_STATS_FLOW_COUNT_LEN);
+   }
+
+   if (oxs_field_set & 1<<3) {
+     uint64_t pkt_count = 0;
+     if(fs) {
+        pkt_count = fs->packet_count;
+        pkt_count = htonll(pkt_count);
+     }
+     oxs_put__(b, OFPXST_OFB_PACKET_COUNT, oxs, &pkt_count,
+               NULL, OXS_STATS_PACKET_COUNT_LEN);
+   }
+
+   if (oxs_field_set & 1<<4) {
+      uint64_t byte_count = 0;
+      if(fs) {
+        byte_count = fs->byte_count;
+        byte_count = htonll(byte_count);
+      }
+      oxs_put__(b, OFPXST_OFB_BYTE_COUNT, oxs, &byte_count,
+                NULL, OXS_STATS_BYTE_COUNT_LEN);
+   }
+
+   stat_len = b->size - start_len;
+   return stat_len;
+}
+
+/* Appends to 'b' an struct ofp_oxs_stat followed by the aggregate flow entry
+ * statistics in OXS format , plus enough zero bytes to pad the data appended
+ * out to a multiple of 8.
+ *
+ * Specify the OpenFlow version in use as 'version'.
+ *
+ * This function can cause 'b''s data to be reallocated.
+ *
+ * Returns the number of bytes appended to 'b', excluding the padding.  Never
+ * returns zero. */
+int
+oxs_put_agg_stat(struct ofpbuf *b, const struct ofputil_aggregate_stats *fs,
+                 enum ofp_version version)
+{
+   int stat_len;
+   struct ofp_oxs_stat *oxs;
+   size_t start_len = b->size;
+
+   ofpbuf_put_uninit(b, sizeof *oxs);
+   stat_len = (ox_put_agg_raw(b, version, fs)
+                + sizeof *oxs);
+   ofpbuf_put_zeros(b, PAD_SIZE(stat_len, 8));
+   oxs = ofpbuf_at(b, start_len, sizeof *oxs);
+   oxs->reserved = htons(0);
+   oxs->length = htons(stat_len);
+
+   return stat_len;
+}
+
diff --git a/lib/ox-stat.h b/lib/ox-stat.h
index 33c30ec..3ff7f07 100644
--- a/lib/ox-stat.h
+++ b/lib/ox-stat.h
@@ -30,4 +30,7 @@ int oxs_put_stat(struct ofpbuf *, const struct ofputil_flow_stats *,
                  enum ofp_version );
 int oxs_pull_stat(struct ofpbuf *,struct ofputil_flow_stats *,
                   uint16_t *);
+int oxs_put_agg_stat(struct ofpbuf *, const struct ofputil_aggregate_stats *,
+                     enum ofp_version);
+int oxs_pull_agg_stat(struct ofpbuf , struct ofputil_aggregate_stats *);
 #endif /* ox_stat.h */
