diff --git a/src/box/lua/tuple.lua b/src/box/lua/tuple.lua
index b9b16bd5452bedf3b32927e7af65693df300d6fb..94f2f732b3097f4099aa0af88ee3f2d1b9a192b3 100644
--- a/src/box/lua/tuple.lua
+++ b/src/box/lua/tuple.lua
@@ -35,6 +35,9 @@ tuple_seek(struct tuple_iterator *it, uint32_t field_no);
 
 const char *
 tuple_next(struct tuple_iterator *it);
+
+void
+tuple_to_buf(struct tuple *tuple, char *buf);
 ]])
 
 local builtin = ffi.C
@@ -107,6 +110,15 @@ local function tuple_unpack(tuple)
     return unpack(tuple_totable(tuple))
 end
 
+-- Set encode hooks for msgpackffi
+local function tuple_to_msgpack(buf, tuple)
+    buf:reserve(tuple._bsize)
+    builtin.tuple_to_buf(tuple, buf.p)
+    buf.p = buf.p + tuple._bsize
+end
+
+msgpackffi.on_encode(ffi.typeof('const struct tuple &'), tuple_to_msgpack)
+
 -- cfuncs table is set by C part
 
 local methods = {
diff --git a/src/box/tuple.h b/src/box/tuple.h
index b608c0b43542e25399de1b9957188f0dd58d2f50..0f94a4c0a1053cc956cf2e9e66b887dbe23a8bab 100644
--- a/src/box/tuple.h
+++ b/src/box/tuple.h
@@ -442,6 +442,13 @@ tuple_to_obuf(struct tuple *tuple, struct obuf *buf);
 void
 tuple_to_tbuf(struct tuple *tuple, struct tbuf *buf);
 
+/**
+ * Store tuple fields in the memory buffer. Buffer must have at least
+ * tuple->bsize bytes.
+ */
+extern "C" void
+tuple_to_buf(struct tuple *tuple, char *buf);
+
 /** Initialize tuple library */
 void
 tuple_init(float slab_alloc_arena, uint32_t slab_alloc_minimal,
diff --git a/src/box/tuple_convert.cc b/src/box/tuple_convert.cc
index b06179bced98581ef826fdd4a4d98add76b1235e..5e1346dd85115dcff78798035294e1278e66159c 100644
--- a/src/box/tuple_convert.cc
+++ b/src/box/tuple_convert.cc
@@ -41,3 +41,9 @@ tuple_to_tbuf(struct tuple *tuple, struct tbuf *buf)
 {
 	tbuf_append(buf, tuple->data, tuple->bsize);
 }
+
+void
+tuple_to_buf(struct tuple *tuple, char *buf)
+{
+	memcpy(buf, tuple->data, tuple->bsize);
+}
diff --git a/test/box/tuple.result b/test/box/tuple.result
index 83ab083eb2b9ad8db9b32e02f932d63f7b826fae..e753073a438dc5962d11dd55a2cdcc5919a4c2ea 100644
--- a/test/box/tuple.result
+++ b/test/box/tuple.result
@@ -377,15 +377,15 @@ t:next(3)
 ...
 t:next(4)
 ---
-- error: '[string "-- tuple.lua (internal file)..."]:65: error: invalid key to ''next'''
+- error: '[string "-- tuple.lua (internal file)..."]:68: error: invalid key to ''next'''
 ...
 t:next(-1)
 ---
-- error: '[string "-- tuple.lua (internal file)..."]:65: error: invalid key to ''next'''
+- error: '[string "-- tuple.lua (internal file)..."]:68: error: invalid key to ''next'''
 ...
 t:next("fdsaf")
 ---
-- error: '[string "-- tuple.lua (internal file)..."]:48: error: invalid key to ''next'''
+- error: '[string "-- tuple.lua (internal file)..."]:51: error: invalid key to ''next'''
 ...
 box.tuple.new({'x', 'y', 'z'}):next()
 ---
@@ -397,7 +397,7 @@ t=space:insert{1953719668}
 ...
 t:next(1684234849)
 ---
-- error: '[string "-- tuple.lua (internal file)..."]:65: error: invalid key to ''next'''
+- error: '[string "-- tuple.lua (internal file)..."]:68: error: invalid key to ''next'''
 ...
 t:next(1)
 ---
@@ -552,7 +552,7 @@ r = {}
 ...
 for _state, val in t:pairs(10) do table.insert(r, val) end
 ---
-- error: '[string "-- tuple.lua (internal file)..."]:65: error: invalid key to ''next'''
+- error: '[string "-- tuple.lua (internal file)..."]:68: error: invalid key to ''next'''
 ...
 r
 ---
@@ -582,6 +582,51 @@ t:pairs("fdsaf")
 - ['a', 'b', 'c']
 - fdsaf
 ...
+--------------------------------------------------------------------------------
+-- test msgpack.encode + tuple
+--------------------------------------------------------------------------------
+msgpackffi = require('msgpackffi')
+---
+...
+t = box.tuple.new({'a', 'b', 'c'})
+---
+...
+msgpack.decode(msgpackffi.encode(t))
+---
+- - a
+  - b
+  - c
+...
+msgpack.decode(msgpack.encode(t))
+---
+- - a
+  - b
+  - c
+...
+msgpack.decode(msgpackffi.encode({1, {'x', 'y', t, 'z'}, 2, 3}))
+---
+- - 1
+  - - x
+    - y
+    - - a
+      - b
+      - c
+    - z
+  - 2
+  - 3
+...
+msgpack.decode(msgpack.encode({1, {'x', 'y', t, 'z'}, 2, 3}))
+---
+- - 1
+  - - x
+    - y
+    - - a
+      - b
+      - c
+    - z
+  - 2
+  - 3
+...
 space:drop()
 ---
 ...
diff --git a/test/box/tuple.test.lua b/test/box/tuple.test.lua
index 5ac99a7087040cc3074da6d0c712eda25083b4cb..1714e4ef2434275d0adcaa6a2ab7900343baa4fe 100644
--- a/test/box/tuple.test.lua
+++ b/test/box/tuple.test.lua
@@ -180,4 +180,16 @@ r
 t:pairs(nil)
 t:pairs("fdsaf")
 
+--------------------------------------------------------------------------------
+-- test msgpack.encode + tuple
+--------------------------------------------------------------------------------
+
+msgpackffi = require('msgpackffi')
+
+t = box.tuple.new({'a', 'b', 'c'})
+msgpack.decode(msgpackffi.encode(t))
+msgpack.decode(msgpack.encode(t))
+msgpack.decode(msgpackffi.encode({1, {'x', 'y', t, 'z'}, 2, 3}))
+msgpack.decode(msgpack.encode({1, {'x', 'y', t, 'z'}, 2, 3}))
+
 space:drop()