diff --git a/app/test-pmd/Makefile b/app/test-pmd/Makefile
index 60ae9b9c1..9254a9440 100644
--- a/app/test-pmd/Makefile
+++ b/app/test-pmd/Makefile
@@ -34,6 +34,10 @@ SRCS-y += csumonly.c
 SRCS-y += icmpecho.c
 SRCS-$(CONFIG_RTE_LIBRTE_IEEE1588) += ieee1588fwd.c
 
+#ifeq ($(CONFIG_RTE_TEST_PMD_NOISY),y)
+#SRCS-y += fifo.c
+#endif
+
 ifeq ($(CONFIG_RTE_LIBRTE_PMD_SOFTNIC)$(CONFIG_RTE_LIBRTE_SCHED),yy)
 SRCS-y += tm.c
 endif
diff --git a/app/test-pmd/fifo.c b/app/test-pmd/fifo.c
new file mode 100644
index 000000000..2271215e8
--- /dev/null
+++ b/app/test-pmd/fifo.c
@@ -0,0 +1,16 @@
+#ifdef RTE_TEST_PMD_NOISY
+//#include <rte_ring.h>
+#include "fifo.h"
+//#include "testpmd.h"
+
+
+struct rte_ring * fifo_init(uint32_t qi)
+{
+	struct noisy_config *n = &noisy_cfg[qi];
+
+	n->f = rte_ring_create("noisy ring", 1024, rte_socket_id(),
+						RING_F_SP_ENQ | RING_F_SC_DEQ);
+	return n->f;
+}
+
+#endif
diff --git a/app/test-pmd/iofwd.c b/app/test-pmd/iofwd.c
index 9dce76efe..85fa000f7 100644
--- a/app/test-pmd/iofwd.c
+++ b/app/test-pmd/iofwd.c
@@ -36,6 +36,7 @@
 #include <rte_flow.h>
 
 #include "testpmd.h"
+#include "fifo.h"
 
 /*
  * Forwarding of packets in I/O mode.
@@ -48,7 +49,7 @@ pkt_burst_io_forward(struct fwd_stream *fs)
 {
 	struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
 	uint16_t nb_rx;
-	uint16_t nb_tx;
+	uint16_t nb_tx = 0;
 	uint32_t retry;
 
 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
@@ -56,6 +57,15 @@ pkt_burst_io_forward(struct fwd_stream *fs)
 	uint64_t end_tsc;
 	uint64_t core_cycles;
 #endif
+#ifdef RTE_TEST_PMD_NOISY
+	const uint64_t freq_khz = rte_get_timer_hz() / 1000;
+	struct noisy_config *ncf = &noisy_cfg[fs->tx_queue];
+	struct rte_mbuf *tmp_pkts[MAX_PKT_BURST];
+	uint16_t nb_enqd;
+	uint16_t nb_deqd = 0;
+	uint64_t delta_ms;
+	uint64_t now;
+#endif
 
 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
 	start_tsc = rte_rdtsc();
@@ -73,8 +83,55 @@ pkt_burst_io_forward(struct fwd_stream *fs)
 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
 	fs->rx_burst_stats.pkt_burst_spread[nb_rx]++;
 #endif
+#ifdef RTE_TEST_PMD_NOISY
+	if (bsize_before_send > 0) {
+		if (rte_ring_free_count(ncf->f) >= nb_rx) {
+			/* enqueue into fifo */
+			nb_enqd = fifo_put(ncf->f, pkts_burst, nb_rx);
+			if (nb_enqd < nb_rx)
+				nb_rx = nb_enqd;
+		} else {
+			/* fifo is full, dequeue first */
+			nb_deqd = fifo_get(ncf->f, tmp_pkts, nb_rx);
+			/* enqueue into fifo */
+			nb_enqd = fifo_put(ncf->f, pkts_burst, nb_deqd);
+			if (nb_enqd < nb_rx)
+				nb_rx = nb_enqd;
+			if (nb_deqd > 0)
+				nb_tx = rte_eth_tx_burst(fs->tx_port,
+						fs->tx_queue, tmp_pkts,
+						nb_deqd);
+		}
+	} else {
+		nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue,
+				pkts_burst, nb_rx);
+	}
+
+	/*
+	 * TX burst queue drain
+	 */
+	if (ncf->prev_time == 0) {
+		now = ncf->prev_time = rte_get_timer_cycles();
+	} else {
+		now = rte_get_timer_cycles();
+	}
+	delta_ms = (now - ncf->prev_time) / freq_khz;
+	if (unlikely(delta_ms >= flush_timer) && flush_timer > 0 && (nb_tx == 0)) {
+		while (fifo_count(ncf->f) > 0) {
+			nb_deqd = fifo_get(ncf->f, tmp_pkts, nb_rx);
+			nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue,
+						 tmp_pkts, nb_deqd);
+			if(rte_ring_empty(ncf->f))
+				break;
+		}
+		ncf->prev_time = now;
+	}
+	if (nb_tx < nb_rx && fs->retry_enabled)
+		*pkts_burst = *tmp_pkts;
+#else
 	nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue,
 			pkts_burst, nb_rx);
+#endif
 	/*
 	 * Retry if necessary
 	 */
diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c
index 97d22b860..8e64055a0 100644
--- a/app/test-pmd/parameters.c
+++ b/app/test-pmd/parameters.c
@@ -621,6 +621,8 @@ launch_args_parse(int argc, char** argv)
 		{ "print-event",		1, 0, 0 },
 		{ "mask-event",			1, 0, 0 },
 		{ "tx-offloads",		1, 0, 0 },
+		{ "buffersize-before-sending",  1, 0, 0 },
+		{ "flush-timer",                1, 0, 0 },
 		{ 0, 0, 0, 0 },
 	};
 
@@ -1102,7 +1104,24 @@ launch_args_parse(int argc, char** argv)
 					rte_exit(EXIT_FAILURE,
 						 "invalid mask-event argument\n");
 				}
-
+#ifdef RTE_TEST_PMD_NOISY
+			if (!strcmp(lgopts[opt_idx].name, "buffersize-before-sending")) {
+				n = atoi(optarg);
+				if (n > 0)
+					bsize_before_send = (uint16_t) n;
+				else
+					rte_exit(EXIT_FAILURE,
+						 "buffersize-before-sending must be > 0\n");
+			}
+			if (!strcmp(lgopts[opt_idx].name, "flush-timer")) {
+				n = atoi(optarg);
+				if (n >= 0)
+					flush_timer = (uint16_t) n;
+				else
+					rte_exit(EXIT_FAILURE,
+						 "flush-timer must be > 0\n");
+			}
+#endif
 			break;
 		case 'h':
 			usage(argv[0]);
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 4c0e2586c..7b8ffdc9c 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -59,6 +59,9 @@
 #ifdef RTE_LIBRTE_LATENCY_STATS
 #include <rte_latencystats.h>
 #endif
+#ifdef RTE_TEST_PMD_NOISY
+#include "fifo.h"
+#endif
 
 #include "testpmd.h"
 
@@ -249,6 +252,18 @@ int16_t tx_free_thresh = RTE_PMD_PARAM_UNSET;
  */
 int16_t tx_rs_thresh = RTE_PMD_PARAM_UNSET;
 
+#ifdef RTE_TEST_PMD_NOISY
+/*
+ * Configurable value of buffered packed before sending.
+ */
+uint16_t bsize_before_send = 0;
+
+/*
+ * Configurable value of packet buffer timeout.
+ */
+uint16_t flush_timer = 0;
+#endif
+
 /*
  * Receive Side Scaling (RSS) configuration.
  */
@@ -401,6 +416,20 @@ static int all_ports_started(void);
 struct gso_status gso_ports[RTE_MAX_ETHPORTS];
 uint16_t gso_max_segment_size = ETHER_MAX_LEN - ETHER_CRC_LEN;
 
+#ifdef RTE_TEST_PMD_NOISY
+#define STRSIZE 256
+#define NOISY_RING "noisy_ring_%d:%d\n"
+struct rte_ring * fifo_init(uint32_t qi, uint32_t pi)
+{
+	struct noisy_config *n = &noisy_cfg[qi];
+	char name[STRSIZE];
+
+	snprintf(name, STRSIZE, NOISY_RING, pi, qi);
+	n->f = rte_ring_create(name, bsize_before_send, rte_socket_id(), 0);
+	return n->f;
+}
+#endif
+
 /*
  * Helper function to check if socket is already discovered.
  * If yes, return positive value. If not, return zero.
@@ -1584,6 +1613,16 @@ start_port(portid_t pid)
 				return -1;
 			}
 		}
+#ifdef RTE_TEST_PMD_NOISY
+		noisy_cfg = (struct noisy_config *) rte_zmalloc("testpmd noisy fifo and timers",
+					nb_txq * sizeof(struct noisy_config),
+					RTE_CACHE_LINE_SIZE);
+		if (noisy_cfg == NULL) {
+			rte_exit(EXIT_FAILURE,
+					"rte_zmalloc(%d struct noisy_config) failed\n",
+					(int)(nb_txq * sizeof(struct noisy_config)));
+		}
+#endif
 		if (port->need_reconfig_queues > 0) {
 			port->need_reconfig_queues = 0;
 			port->tx_conf.txq_flags = ETH_TXQ_FLAGS_IGNORE;
@@ -1591,6 +1630,11 @@ start_port(portid_t pid)
 			port->tx_conf.offloads = port->dev_conf.txmode.offloads;
 			/* setup tx queues */
 			for (qi = 0; qi < nb_txq; qi++) {
+#ifdef RTE_TEST_PMD_NOISY
+				if (!fifo_init(qi, pi) && bsize_before_send > 0)
+					rte_exit(EXIT_FAILURE, "%s\n",
+						 rte_strerror(rte_errno));
+#endif
 				if ((numa_support) &&
 					(txring_numa[pi] != NUMA_NO_CONFIG))
 					diag = rte_eth_tx_queue_setup(pi, qi,
@@ -1755,6 +1799,10 @@ stop_port(portid_t pid)
 			RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
 			printf("Port %d can not be set into stopped\n", pi);
 		need_check_link_status = 1;
+
+#ifdef  RTE_TEST_PMD_NOISY
+		rte_free(noisy_cfg);
+#endif
 	}
 	if (need_check_link_status && !no_link_check)
 		check_all_ports_link_status(RTE_PORT_ALL);
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 153abea05..a6c1a17bb 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -9,6 +9,9 @@
 #include <rte_bus_pci.h>
 #include <rte_gro.h>
 #include <rte_gso.h>
+#ifdef RTE_TEST_PMD_NOISY
+#include "fifo.h"
+#endif
 
 #define RTE_PORT_ALL            (~(portid_t)0x0)
 
@@ -109,6 +112,15 @@ struct fwd_stream {
 #endif
 };
 
+#ifdef RTE_TEST_PMD_NOISY
+struct noisy_config {
+	struct rte_ring *f;
+	uint64_t prev_time;
+};
+struct noisy_config *noisy_cfg;
+#endif
+
+
 /** Descriptor for a single flow. */
 struct port_flow {
 	size_t size; /**< Allocated space including data[]. */
@@ -382,6 +394,9 @@ extern int8_t rx_drop_en;
 extern int16_t tx_free_thresh;
 extern int16_t tx_rs_thresh;
 
+extern uint16_t bsize_before_send;
+extern uint16_t flush_timer;
+
 extern uint8_t dcb_config;
 extern uint8_t dcb_test;
 
diff --git a/config/common_base b/config/common_base
index ad03cf433..194e5901f 100644
--- a/config/common_base
+++ b/config/common_base
@@ -808,6 +808,7 @@ CONFIG_RTE_PROC_INFO=n
 CONFIG_RTE_TEST_PMD=y
 CONFIG_RTE_TEST_PMD_RECORD_CORE_CYCLES=n
 CONFIG_RTE_TEST_PMD_RECORD_BURST_STATS=n
+CONFIG_RTE_TEST_PMD_NOISY=y
 
 #
 # Compile the bbdev test application
