diff --git a/doc/user/stored-procedures.xml b/doc/user/stored-procedures.xml
index 1537a32feedaaf0ea3ecddc1ab33805532664900..e326717c030071caaf4c4136b8e9982ed5a40b01 100644
--- a/doc/user/stored-procedures.xml
+++ b/doc/user/stored-procedures.xml
@@ -726,6 +726,31 @@ localhost> lua box.select_reverse_range(4, 1, 2, '1')
                 integer, and stores the integer in the resulting
                 string, low byte first,
                 </member>
+                <member><code>n</code> &mdash; converts Lua
+                variable to a 2-byte
+                integer, and stores the integer in the resulting
+                string, big endian,
+                </member>
+                <member><code>N</code> &mdash; converts Lua
+                variable to a 4-byte
+                integer, and stores the integer in the resulting
+                string, big endian,
+                </member>
+                <member><code>Q</code> &mdash; converts Lua
+                variable to a 8-byte
+                integer, and stores the integer in the resulting
+                string, big endian,
+                </member>
+                <member><code>f</code> &mdash; converts Lua
+                variable to a 4-byte
+                float, and stores the float in the resulting
+                string,
+                </member>
+                <member><code>d</code> &mdash; converts Lua
+                variable to a 8-byte
+                double, and stores the double in the resulting
+                string,
+                </member>
                 <member><code>w</code> &mdash; converts Lua
                 integer to a BER-encoded integer,
                 </member>
diff --git a/src/box/box_lua.cc b/src/box/box_lua.cc
index 4848f8fbbb28197df66a2d8b23455c9fbfd6071a..7672b80bb16626aed6c8f05ee81fb63918115be0 100644
--- a/src/box/box_lua.cc
+++ b/src/box/box_lua.cc
@@ -42,6 +42,7 @@ extern "C" {
 #include <lj_ctype.h>
 #include <lj_cdata.h>
 #include <lj_cconv.h>
+#include <endian.h>
 } /* extern "C" */
 
 #include "pickle.h"
@@ -1477,6 +1478,11 @@ lbox_pack(struct lua_State *L)
 	luaL_buffinit(L, &b);
 
 	struct lua_field field;
+	double dbl;
+	float flt;
+	uint16_t u16;
+	uint32_t u32;
+	uint64_t u64;
 	while (*format) {
 		if (i > nargs)
 			luaL_error(L, "box.pack: argument count does not match "
@@ -1497,6 +1503,13 @@ lbox_pack(struct lua_State *L)
 				luaL_error(L, "box.pack: expected 16-bit int");
 			luaL_addlstring(&b, field.data, sizeof(uint16_t));
 			break;
+		case 'n':
+			/* signed and unsigned 16-bit big endian integers */
+			if (field.type != NUM || field.u32 > UINT16_MAX)
+				luaL_error(L, "box.pack: expected 16-bit int");
+			u16 = htobe16( (uint16_t) field.u32 );
+			luaL_addlstring(&b, (char *)&u16, sizeof(u16));
+			break;
 		case 'I':
 		case 'i':
 			/* signed and unsigned 32-bit integers */
@@ -1504,6 +1517,13 @@ lbox_pack(struct lua_State *L)
 				luaL_error(L, "box.pack: expected 32-bit int");
 			luaL_addlstring(&b, field.data, sizeof(uint32_t));
 			break;
+		case 'N':
+			/* signed and unsigned 32-bit big endian integers */
+			if (field.type != NUM)
+				luaL_error(L, "box.pack: expected 32-bit int");
+			u32 = htobe32( field.u32 );
+			luaL_addlstring(&b, (char *)&u32, sizeof(uint32_t));
+			break;
 		case 'L':
 		case 'l':
 			/* signed and unsigned 64-bit integers */
@@ -1511,12 +1531,34 @@ lbox_pack(struct lua_State *L)
 				luaL_addlstring(&b, field.data, field.len);
 			} else if (field.type == NUM) {
 				/* extend 32-bit value to 64-bit */
-				uint64_t val = field.u32;
-				luaL_addlstring(&b, (char *)&val, sizeof(val));
+				u64 = field.u32;
+				luaL_addlstring(&b, (char *)&u64, sizeof(u64));
 			} else {
 				luaL_error(L, "box.pack: expected 64-bit int");
 			}
 			break;
+		case 'Q':
+		case 'q':
+			/* signed and unsigned 64-bit integers */
+			if (field.type == NUM64) {
+				u64 = *(uint64_t*) field.data;
+			} else if (field.type == NUM) {
+				/* extend 32-bit value to 64-bit */
+				u64 = field.u32;
+			} else {
+				luaL_error(L, "box.pack: expected 64-bit int");
+			}
+			u64 = htobe64(u64);
+			luaL_addlstring(&b, (char *)&u64, sizeof(u64));
+			break;
+		case 'd':
+			dbl = (double) lua_tonumber(L, i);
+			luaL_addlstring(&b, (char *) &dbl, sizeof(dbl));
+			break;
+		case 'f':
+			flt = (float) lua_tonumber(L, i);
+			luaL_addlstring(&b, (char *) &flt, sizeof(flt));
+			break;
 		case 'w':
 			/* Perl 'pack' BER-encoded integer */
 			if (field.type != NUM)
@@ -1618,6 +1660,8 @@ lbox_unpack(struct lua_State *L)
 	uint8_t  u8buf;
 	uint16_t u16buf;
 	uint32_t u32buf;
+	double dbl;
+	float flt;
 
 #define CHECK_SIZE(cur) if (unlikely((cur) >= end)) {	                \
 	luaL_error(L, "box.unpack('%c'): got %d bytes (expected: %d+)",	\
@@ -1637,17 +1681,46 @@ lbox_unpack(struct lua_State *L)
 			lua_pushnumber(L, u16buf);
 			s += 2;
 			break;
+		case 'n':
+			CHECK_SIZE(s + 1);
+			u16buf = be16toh(*(uint16_t *) s);
+			lua_pushnumber(L, u16buf);
+			s += 2;
+			break;
 		case 'i':
 			CHECK_SIZE(s + 3);
 			u32buf = *(uint32_t *) s;
 			lua_pushnumber(L, u32buf);
 			s += 4;
 			break;
+		case 'N':
+			CHECK_SIZE(s + 3);
+			u32buf = be32toh(*(uint32_t *) s);
+			lua_pushnumber(L, u32buf);
+			s += 4;
+			break;
 		case 'l':
 			CHECK_SIZE(s + 7);
 			luaL_pushnumber64(L, *(uint64_t*) s);
 			s += 8;
 			break;
+		case 'q':
+			CHECK_SIZE(s + 7);
+			luaL_pushnumber64(L, be64toh(*(uint64_t*) s));
+			s += 8;
+			break;
+		case 'd':
+			CHECK_SIZE(s + 7);
+			dbl = *(double *) s;
+			lua_pushnumber(L, dbl);
+			s += 8;
+			break;
+		case 'f':
+			CHECK_SIZE(s + 3);
+			flt = *(float *) s;
+			lua_pushnumber(L, flt);
+			s += 4;
+			break;
 		case 'w':
 			/* pick_varint32 throws exception on error. */
 			u32buf = pick_varint32(&s, end);