diff --git a/extra/exports b/extra/exports
index 47cf1eb85d7174517f18a6544915757a688af857..3660fc08d9b19a14d07cc3e2d6bf347c1183e2e4 100644
--- a/extra/exports
+++ b/extra/exports
@@ -454,6 +454,7 @@ tnt_iconv_open
 tnt_interval_to_string
 tnt_interval_interval_sub
 tnt_interval_interval_add
+tnt_interval_unpack
 tnt_mp_decode_double
 tnt_mp_decode_extl
 tnt_mp_decode_float
@@ -462,10 +463,12 @@ tnt_mp_encode_decimal
 tnt_mp_encode_double
 tnt_mp_encode_error
 tnt_mp_encode_float
+tnt_mp_encode_interval
 tnt_mp_encode_uuid
 tnt_mp_sizeof_datetime
 tnt_mp_sizeof_decimal
 tnt_mp_sizeof_error
+tnt_mp_sizeof_interval
 tnt_mp_sizeof_uuid
 tnt_rl_get_screen_size
 tnt_ssl_cert_paths_discover
diff --git a/src/lua/msgpackffi.lua b/src/lua/msgpackffi.lua
index b665afb304cebb8ae232707ccb49085f472d7871..46a597e20d16fdc9c009003a2583ae12e5189205 100644
--- a/src/lua/msgpackffi.lua
+++ b/src/lua/msgpackffi.lua
@@ -34,6 +34,10 @@ uint32_t
 tnt_mp_sizeof_datetime(const struct datetime *date);
 char *
 tnt_mp_encode_datetime(char *data, const struct datetime *date);
+char *
+tnt_mp_encode_interval(char *data, const struct interval *itv);
+uint32_t
+tnt_mp_sizeof_interval(const struct interval *itv);
 float
 tnt_mp_decode_float(const char **data);
 double
@@ -50,6 +54,8 @@ void
 error_unref(struct error *e);
 struct datetime *
 tnt_datetime_unpack(const char **data, uint32_t len, struct datetime *date);
+struct interval *
+tnt_interval_unpack(const char **data, struct interval *itv);
 ]])
 
 local strict_alignment = (jit.arch == 'arm')
@@ -161,6 +167,11 @@ local function encode_datetime(buf, date)
     builtin.tnt_mp_encode_datetime(p, date)
 end
 
+local function encode_interval(buf, itv)
+    local p = buf:alloc(builtin.tnt_mp_sizeof_interval(itv))
+    builtin.tnt_mp_encode_interval(p, itv)
+end
+
 local function encode_int(buf, num)
     if num >= 0 then
         if num <= 0x7f then
@@ -350,6 +361,7 @@ on_encode(ffi.typeof('decimal_t'), encode_decimal)
 on_encode(ffi.typeof('struct tt_uuid'), encode_uuid)
 on_encode(ffi.typeof('const struct error &'), encode_error)
 on_encode(ffi.typeof('struct datetime'), encode_datetime)
+on_encode(ffi.typeof('struct interval'), encode_interval)
 
 --------------------------------------------------------------------------------
 -- Decoder
@@ -563,6 +575,12 @@ local ext_decoder = {
         builtin.tnt_datetime_unpack(data, len, dt)
         return dt
     end,
+    -- MP_INTERVAL
+    [6] = function(data)
+        local itv = ffi.new("struct interval")
+        builtin.tnt_interval_unpack(data, itv)
+        return itv
+    end,
 }
 
 local function decode_ext(data)
diff --git a/src/lua/tnt_datetime.c b/src/lua/tnt_datetime.c
index 86c36417bb653b43dbe60bb9f15a18e702811530..e0a60ac9561ae8bae63187ed17bd351b2fafd809 100644
--- a/src/lua/tnt_datetime.c
+++ b/src/lua/tnt_datetime.c
@@ -6,6 +6,7 @@
 
 #include <datetime.h>
 #include <mp_datetime.h>
+#include <mp_interval.h>
 
 size_t
 tnt_datetime_strftime(const struct datetime *date, char *buf, size_t len,
@@ -82,3 +83,9 @@ tnt_interval_interval_add(struct interval *lhs, const struct interval *rhs)
 {
 	return interval_interval_add(lhs, rhs);
 }
+
+struct interval *
+tnt_interval_unpack(const char **data, struct interval *itv)
+{
+	return interval_unpack(data, itv);
+}
diff --git a/src/lua/tnt_msgpuck.c b/src/lua/tnt_msgpuck.c
index 0a85a100689be5776ee6ae622b04783cd58726a3..5ef0ffd1a0b1a5d0aeb8af6aa032cbf72c8d2af9 100644
--- a/src/lua/tnt_msgpuck.c
+++ b/src/lua/tnt_msgpuck.c
@@ -31,6 +31,7 @@
 
 #include "msgpuck.h"
 #include "tnt_msgpuck.h"
+#include "mp_interval.h"
 
 char *
 tnt_mp_encode_float(char *data, float num)
@@ -109,3 +110,15 @@ tnt_mp_sizeof_datetime(const struct datetime *date)
 {
 	return mp_sizeof_datetime(date);
 }
+
+char *
+tnt_mp_encode_interval(char *data, const struct interval *itv)
+{
+	return mp_encode_interval(data, itv);
+}
+
+uint32_t
+tnt_mp_sizeof_interval(const struct interval *itv)
+{
+	return mp_sizeof_interval(itv);
+}
diff --git a/src/lua/tnt_msgpuck.h b/src/lua/tnt_msgpuck.h
index fc8ffcbf87b8bc5d4d944eea3ed2f66109cb047b..4cd0e5527eb3c7b66daad72d83d3e4fbf7372fc7 100644
--- a/src/lua/tnt_msgpuck.h
+++ b/src/lua/tnt_msgpuck.h
@@ -46,6 +46,8 @@ extern "C" {
 #include "box/mp_error.h"
 #include "mp_uuid.h"
 
+struct interval;
+
 char *
 tnt_mp_encode_decimal(char *data, const decimal_t *dec);
 
@@ -70,6 +72,14 @@ tnt_mp_encode_datetime(char *data, const struct datetime *date);
 uint32_t
 tnt_mp_sizeof_datetime(const struct datetime *date);
 
+/** Wrapper around mp_encode_interval(). */
+char *
+tnt_mp_encode_interval(char *data, const struct interval *itv);
+
+/** Wrapper around mp_sizeof_interval(). */
+uint32_t
+tnt_mp_sizeof_interval(const struct interval *itv);
+
 #if defined(__cplusplus)
 } /* extern "C" */
 #endif /* defined(__cplusplus) */
diff --git a/test/app-luatest/interval_test.lua b/test/app-luatest/interval_test.lua
index 6bd3896a5e2b9259f4d1dc00c736aaa511079af6..5e9ce3880876a6146eaf7a836aad5da2c8900da8 100644
--- a/test/app-luatest/interval_test.lua
+++ b/test/app-luatest/interval_test.lua
@@ -1,6 +1,7 @@
 local t = require('luatest')
 local g = t.group()
 local msgpack = require('msgpack')
+local msgpackffi = require('msgpackffi')
 local itv = require('datetime').interval
 
 -- Interval is 1 year, 127 days and 15 minutes
@@ -24,3 +25,11 @@ end
 g.test_check_interval_encode = function()
     t.assert_equals(bin, msgpack.encode(val))
 end
+
+g.test_check_interval_decode_ffi = function()
+    t.assert_equals(msgpackffi.decode(bin), val)
+end
+
+g.test_check_interval_encode_ffi = function()
+    t.assert_equals(bin, msgpackffi.encode(val))
+end