diff --git a/src/Makefile.test.include b/src/Makefile.test.include
--- a/src/Makefile.test.include
+++ b/src/Makefile.test.include
@@ -87,6 +87,7 @@
   test/multisig_tests.cpp \
   test/net_tests.cpp \
   test/netbase_tests.cpp \
+  test/op_reversebytes_tests.cpp \
   test/pmt_tests.cpp \
   test/policyestimator_tests.cpp \
   test/pow_tests.cpp \
diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp
--- a/src/script/interpreter.cpp
+++ b/src/script/interpreter.cpp
@@ -1235,6 +1235,21 @@
                         stacktop(-1) = std::move(n2);
                     } break;
 
+                    case OP_REVERSEBYTES: {
+                        if (!(flags & SCRIPT_ENABLE_OP_REVERSEBYTES)) {
+                            return set_error(serror, ScriptError::BAD_OPCODE);
+                        }
+
+                        // (in -- out)
+                        if (stack.size() < 1) {
+                            return set_error(
+                                serror, ScriptError::INVALID_STACK_OPERATION);
+                        }
+
+                        valtype &data = stacktop(-1);
+                        std::reverse(data.begin(), data.end());
+                    } break;
+
                     //
                     // Conversion operations
                     //
diff --git a/src/script/script.h b/src/script/script.h
--- a/src/script/script.h
+++ b/src/script/script.h
@@ -182,6 +182,9 @@
     OP_CHECKDATASIG = 0xba,
     OP_CHECKDATASIGVERIFY = 0xbb,
 
+    // additional byte string operations
+    OP_REVERSEBYTES = 0xbc,
+
     // The first op_code value after all defined opcodes
     FIRST_UNDEFINED_OP_VALUE,
 
diff --git a/src/script/script.cpp b/src/script/script.cpp
--- a/src/script/script.cpp
+++ b/src/script/script.cpp
@@ -232,6 +232,8 @@
             return "OP_CHECKDATASIG";
         case OP_CHECKDATASIGVERIFY:
             return "OP_CHECKDATASIGVERIFY";
+        case OP_REVERSEBYTES:
+            return "OP_REVERSEBYTES";
 
         // expansion
         case OP_NOP1:
diff --git a/src/script/script_flags.h b/src/script/script_flags.h
--- a/src/script/script_flags.h
+++ b/src/script/script_flags.h
@@ -111,6 +111,9 @@
     // Note: The Segwit Recovery feature is a (currently moot) exception to
     // VERIFY_INPUT_SIGCHECKS
     SCRIPT_VERIFY_INPUT_SIGCHECKS = (1U << 22),
+    
+    // Whether the new OP_REVERSEBYTES opcode can be used.
+    SCRIPT_ENABLE_OP_REVERSEBYTES = (1U << 23),
 
     // A utility flag to decide whether VerifyScript should output the correct
     // sigchecks value or to report zero.
diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt
--- a/src/test/CMakeLists.txt
+++ b/src/test/CMakeLists.txt
@@ -127,6 +127,7 @@
 		multisig_tests.cpp
 		net_tests.cpp
 		netbase_tests.cpp
+		op_reversebytes_tests.cpp
 		pmt_tests.cpp
 		policyestimator_tests.cpp
 		pow_tests.cpp
diff --git a/src/test/data/script_tests.json b/src/test/data/script_tests.json
--- a/src/test/data/script_tests.json
+++ b/src/test/data/script_tests.json
@@ -254,8 +254,8 @@
 
 ["0", "IF CHECKDATASIG ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"],
 ["0", "IF CHECKDATASIGVERIFY ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"],
-["0", "IF 0xbc ELSE 1 ENDIF", "P2SH,STRICTENC", "OK", "opcodes >= FIRST_UNDEFINED_OP_VALUE invalid if executed"],
-["0", "IF 0xbd ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"],
+["0", "IF REVERSEBYTES ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"],
+["0", "IF 0xbd ELSE 1 ENDIF", "P2SH,STRICTENC", "OK", "opcodes >= FIRST_UNDEFINED_OP_VALUE invalid if executed"],
 ["0", "IF 0xbe ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"],
 ["0", "IF 0xbf ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"],
 ["0", "IF 0xc0 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"],
@@ -961,6 +961,40 @@
     "P2SH,STRICTENC", "OK", "SPLIT, maximum length with empty string"
 ],
 
+["REVERSEBYTES"],
+["0", "REVERSEBYTES 0 EQUAL", "P2SH", "BAD_OPCODE", "REVERSEBYTES, not yet activated in executed branch"],
+["0x02 0xbeef", "REVERSEBYTES 0x02 0xefbe EQUAL", "P2SH", "BAD_OPCODE", "REVERSEBYTES, not yet activated in executed branch"],
+["", "REVERSEBYTES 0 EQUAL", "P2SH,REVERSEBYTES", "INVALID_STACK_OPERATION", "REVERSEBYTES, empty stack"],
+["0", "REVERSEBYTES 0 EQUAL", "P2SH,REVERSEBYTES", "OK", "REVERSEBYTES, empty data"],
+["0x01 0x99", "REVERSEBYTES 0x01 0x99 EQUAL", "P2SH,REVERSEBYTES", "OK", "REVERSEBYTES, 1 byte"],
+["0x02 0xbeef", "REVERSEBYTES 0x02 0xefbe EQUAL", "P2SH,REVERSEBYTES", "OK", "REVERSEBYTES, 2 bytes"],
+["0x03 0xdeada1", "REVERSEBYTES 0x03 0xa1adde EQUAL", "P2SH,REVERSEBYTES", "OK", "REVERSEBYTES, 3 bytes"],
+["0x04 0xdeadbeef", "REVERSEBYTES 0x04 0xefbeadde EQUAL", "P2SH,REVERSEBYTES", "OK", "REVERSEBYTES, 4 bytes"],
+["'Bitcoin:_A_peer-to-peer_electronic_cash_system'", "REVERSEBYTES 'metsys_hsac_cinortcele_reep-ot-reep_A_:nioctiB' EQUAL", "P2SH,REVERSEBYTES", "OK", "REVERSEBYTES, whitepaper title"],
+[
+    "'zngyivniryrgefgnvqwfwqplmramujzilzyrsdvinxfkfmuowdpuzycnzbupwwpzrfxsbyrhdlsyixyzysodseayvvrtbsfxtikrjwkbduulrjyjlwlaigomhyohsukawdwbrpuacdijzzgxhataguajvuopuktvtklwhsxqvzzfttpdgnxtnbpsiqecxurlczqmoxznlsuejvneiyejetcxlblzrydscnrbydnqytorstjtuzlbbtbyzfiniuehbisqnqhvexylhohjiyiknzgjowvobsrwcxyfowqcvakgdolwpltfcxtrhuysrrvtprzpsucgogsjapdkrbobpxccqgkdumskaleycwsbkabdkuukqiyizceduplmauszwjdzptvmthxocwrignxjogxsvrsjrrlecvdmazlpfkgmskiqqitrevuwiisvpxvkeypzaqjwwiozvmahmtvtjpbolwrymvzfstopzcexalirwbbcqgjvfjfuirrcnlgcfyqnafhh'",
+    "REVERSEBYTES 'hhfanqyfcglncrriufjfvjgqcbbwrilaxeczpotsfzvmyrwlobpjtvtmhamvzoiwwjqazpyekvxpvsiiwuvertiqqiksmgkfplzamdvcelrrjsrvsxgojxngirwcoxhtmvtpzdjwzsuamlpudecziyiqkuukdbakbswcyelaksmudkgqccxpbobrkdpajsgogcuspzrptvrrsyuhrtxcftlpwlodgkavcqwofyxcwrsbovwojgznkiyijhohlyxevhqnqsibheuinifzybtbblzutjtsrotyqndybrncsdyrzlblxctejeyienvjeuslnzxomqzclruxceqispbntxngdpttfzzvqxshwlktvtkupouvjaugatahxgzzjidcauprbwdwakushoyhmogialwljyjrluudbkwjrkitxfsbtrvvyaesdosyzyxiysldhrybsxfrzpwwpubzncyzupdwoumfkfxnivdsryzlizjumarmlpqwfwqvngfegryrinviygnz' EQUAL",
+    "P2SH,REVERSEBYTES", "OK", "REVERSEBYTES, 520 bytes"
+],
+["0x03 0x123456", "REVERSEBYTES 0x03 0x563412 OP_EQUAL", "P2SH,REVERSEBYTES", "OK", "REVERSEBYTES, 3 bytes equal"],
+["0x06 0x020406080a0c", "DUP REVERSEBYTES REVERSEBYTES OP_EQUAL", "P2SH,REVERSEBYTES", "OK", "REVERSEBYTES, 3 bytes double reverse equal"],
+["'Bitcoin:_A_peer-to-peer_electronic_cash_system'", "DUP REVERSEBYTES REVERSEBYTES OP_EQUAL", "P2SH,REVERSEBYTES", "OK", "REVERSEBYTES, whitepaper title double reverse equal"],
+[
+    "'zngyivniryrgefgnvqwfwqplmramujzilzyrsdvinxfkfmuowdpuzycnzbupwwpzrfxsbyrhdlsyixyzysodseayvvrtbsfxtikrjwkbduulrjyjlwlaigomhyohsukawdwbrpuacdijzzgxhataguajvuopuktvtklwhsxqvzzfttpdgnxtnbpsiqecxurlczqmoxznlsuejvneiyejetcxlblzrydscnrbydnqytorstjtuzlbbtbyzfiniuehbisqnqhvexylhohjiyiknzgjowvobsrwcxyfowqcvakgdolwpltfcxtrhuysrrvtprzpsucgogsjapdkrbobpxccqgkdumskaleycwsbkabdkuukqiyizceduplmauszwjdzptvmthxocwrignxjogxsvrsjrrlecvdmazlpfkgmskiqqitrevuwiisvpxvkeypzaqjwwiozvmahmtvtjpbolwrymvzfstopzcexalirwbbcqgjvfjfuirrcnlgcfyqnafhh'",
+    "DUP REVERSEBYTES REVERSEBYTES OP_EQUAL",
+    "P2SH,REVERSEBYTES",
+    "OK",
+    "REVERSEBYTES, 520 bytes double reverse equal"
+],
+["0x05 0x0102030201", "DUP REVERSEBYTES OP_EQUAL", "P2SH,REVERSEBYTES", "OK", "REVERSEBYTES, palindrome 1"],
+["0x08 0x7766554444556677", "DUP REVERSEBYTES OP_EQUAL", "P2SH,REVERSEBYTES", "OK", "REVERSEBYTES, palindrome 2"],
+["'madam'", "DUP REVERSEBYTES OP_EQUAL", "P2SH,REVERSEBYTES", "OK", "REVERSEBYTES, palindrome 3"],
+["'racecar'", "DUP REVERSEBYTES OP_EQUAL", "P2SH,REVERSEBYTES", "OK", "REVERSEBYTES, palindrome 4"],
+["'redrum_siris_murder'", "DUP REVERSEBYTES OP_EQUAL", "P2SH,REVERSEBYTES", "OK", "REVERSEBYTES, palindrome 5"],
+["'step_on_no_pets'", "DUP REVERSEBYTES OP_EQUAL", "P2SH,REVERSEBYTES", "OK", "REVERSEBYTES, palindrome 6"],
+["'Bitcoin:_A_peer-to-peer_electronic_cash_system'", "DUP REVERSEBYTES OP_EQUAL", "P2SH,REVERSEBYTES", "EVAL_FALSE", "REVERSEBYTES, non-palindrome 1"],
+["0x02 0x1234", "DUP REVERSEBYTES OP_EQUAL", "P2SH,REVERSEBYTES", "EVAL_FALSE", "REVERSEBYTES, non-palindrome 2"],
+
 ["NUM2BIN"],
 ["", "NUM2BIN 0 EQUAL", "P2SH,STRICTENC", "INVALID_STACK_OPERATION", "NUM2BIN, empty stack"],
 ["0", "NUM2BIN 0 EQUAL", "P2SH,STRICTENC", "INVALID_STACK_OPERATION", "NUM2BIN, one parameter"],
@@ -1241,8 +1275,8 @@
  "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS", "Discouraged NOP10 in redeemScript"],
 
 ["0x50","1", "P2SH,STRICTENC", "BAD_OPCODE", "opcode 0x50 is reserved"],
-["1", "IF 0xbc ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE", "opcodes >= FIRST_UNDEFINED_OP_VALUE invalid if executed"],
-["1", "IF 0xbd ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"],
+["1", "IF REVERSEBYTES ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE", "opcode OP_REVERSEBYTES invalid if executed normally"],
+["1", "IF 0xbd ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE", "opcodes >= FIRST_UNDEFINED_OP_VALUE invalid if executed"],
 ["1", "IF 0xbe ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"],
 ["1", "IF 0xbf ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"],
 ["1", "IF 0xc0 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"],
@@ -1362,7 +1396,7 @@
 ["1","RESERVED", "P2SH,STRICTENC", "BAD_OPCODE", "OP_RESERVED is reserved"],
 ["1","RESERVED1", "P2SH,STRICTENC", "BAD_OPCODE", "OP_RESERVED1 is reserved"],
 ["1","RESERVED2", "P2SH,STRICTENC", "BAD_OPCODE", "OP_RESERVED2 is reserved"],
-["1","0xbc", "P2SH,STRICTENC", "BAD_OPCODE", "0xbc == FIRST_UNDEFINED_OP_VALUE"],
+["1","0xbd", "P2SH,STRICTENC", "BAD_OPCODE", "0xbd == FIRST_UNDEFINED_OP_VALUE"],
 
 ["2147483648", "1ADD 1", "P2SH,STRICTENC", "UNKNOWN_ERROR", "We cannot do math on 5-byte integers"],
 ["2147483648", "NEGATE 1", "P2SH,STRICTENC", "UNKNOWN_ERROR", "We cannot do math on 5-byte integers"],
diff --git a/src/test/op_reversebytes_tests.cpp b/src/test/op_reversebytes_tests.cpp
new file mode 100644
--- /dev/null
+++ b/src/test/op_reversebytes_tests.cpp
@@ -0,0 +1,156 @@
+// Copyright (c) 2020 The Bitcoin developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <script/interpreter.h>
+#include <script/script.h>
+
+#include <test/lcg.h>
+#include <test/test_bitcoin.h>
+
+#include <boost/test/unit_test.hpp>
+
+typedef std::vector<uint8_t> valtype;
+typedef std::vector<valtype> stacktype;
+
+BOOST_FIXTURE_TEST_SUITE(op_reversebytes_tests, BasicTestingSetup)
+
+struct ReverseTestCase {
+    const valtype item;
+    const valtype reversed_item;
+};
+
+static void CheckErrorWithFlags(const uint32_t flags,
+                                const stacktype &original_stack,
+                                const CScript &script,
+                                const ScriptError expected) {
+    BaseSignatureChecker sigchecker;
+    ScriptError err = ScriptError::OK;
+    stacktype stack{original_stack};
+    bool r = EvalScript(stack, script, flags, sigchecker, &err);
+    BOOST_CHECK(!r);
+    BOOST_CHECK(err == expected);
+}
+
+static void CheckPassWithFlags(const uint32_t flags,
+                               const stacktype &original_stack,
+                               const CScript &script,
+                               const stacktype &expected) {
+    BaseSignatureChecker sigchecker;
+    ScriptError err = ScriptError::OK;
+    stacktype stack{original_stack};
+    bool r = EvalScript(stack, script, flags, sigchecker, &err);
+    BOOST_CHECK(r);
+    BOOST_CHECK(err == ScriptError::OK);
+    BOOST_CHECK(stack == expected);
+}
+
+/**
+ * Verifies that the given error occurs with OP_REVERSEBYTES enabled
+ * and that BAD_OPCODE occurs if disabled.
+ */
+static void CheckErrorIfEnabled(const uint32_t flags,
+                                const stacktype &original_stack,
+                                const CScript &script,
+                                const ScriptError expected) {
+    CheckErrorWithFlags(flags | SCRIPT_ENABLE_OP_REVERSEBYTES, original_stack,
+                        script, expected);
+    CheckErrorWithFlags(flags & ~SCRIPT_ENABLE_OP_REVERSEBYTES, original_stack,
+                        script, ScriptError::BAD_OPCODE);
+}
+
+/**
+ * Verifies that the given stack results with OP_REVERSEBYTES enabled
+ * and that BAD_OPCODE occurs if disabled.
+ */
+static void CheckPassIfEnabled(const uint32_t flags,
+                               const stacktype &original_stack,
+                               const CScript &script,
+                               const stacktype &expected) {
+    CheckPassWithFlags(flags | SCRIPT_ENABLE_OP_REVERSEBYTES, original_stack,
+                       script, expected);
+    CheckErrorWithFlags(flags & ~SCRIPT_ENABLE_OP_REVERSEBYTES, original_stack,
+                        script, ScriptError::BAD_OPCODE);
+}
+
+/**
+ * Verifies a given reverse test case.
+ * Checks both if <item> OP_REVERSEBYTES results in <reversed_item> and
+ * whether double-reversing <item> is a no-op.
+ */
+static void CheckPassReverse(const uint32_t flags,
+                             const ReverseTestCase &reverse_case) {
+    CheckPassIfEnabled(flags, {reverse_case.item}, CScript() << OP_REVERSEBYTES,
+                       {reverse_case.reversed_item});
+    CheckPassIfEnabled(flags, {reverse_case.item},
+                       CScript() << OP_DUP << OP_REVERSEBYTES << OP_REVERSEBYTES
+                                 << OP_EQUALVERIFY,
+                       {});
+}
+
+BOOST_AUTO_TEST_CASE(op_reversebytes_tests) {
+    MMIXLinearCongruentialGenerator lcg;
+    // Manual tests.
+    std::vector<ReverseTestCase> test_cases({
+        {{}, {}},
+        {{99}, {99}},
+        {{0xde, 0xad}, {0xad, 0xde}},
+        {{0xde, 0xad, 0xa1}, {0xa1, 0xad, 0xde}},
+        {{0xde, 0xad, 0xbe, 0xef}, {0xef, 0xbe, 0xad, 0xde}},
+        {{0x12, 0x34, 0x56}, {0x56, 0x34, 0x12}},
+    });
+
+    // Palindrome tests, they are their own reverse.
+    std::vector<valtype> palindromes;
+    palindromes.reserve(MAX_SCRIPT_ELEMENT_SIZE);
+
+    // Generated tests:
+    // - for iota(n) mod 256, n = 0,..,520.
+    // - for random bitstrings, n = 0,..,520.
+    // - for palindromes 0,..,n,..,0.
+    for (size_t datasize = 0; datasize <= MAX_SCRIPT_ELEMENT_SIZE; ++datasize) {
+        valtype iota_data, random_data, palindrome;
+        iota_data.reserve(datasize);
+        random_data.reserve(datasize);
+        palindrome.reserve(datasize);
+        for (size_t item = 0; item < datasize; ++item) {
+            iota_data.emplace_back(item % 256);
+            random_data.emplace_back(lcg.next() % 256);
+            palindrome.emplace_back(
+                (item < (datasize + 1) / 2 ? item : datasize - item - 1) % 256);
+        }
+        test_cases.push_back(
+            {iota_data, {iota_data.rbegin(), iota_data.rend()}});
+        test_cases.push_back(
+            {random_data, {random_data.rbegin(), random_data.rend()}});
+        palindromes.push_back(palindrome);
+    }
+
+    for (int i = 0; i < 4096; i++) {
+        // Generate random flags.
+        uint32_t flags = lcg.next();
+
+        // Empty stack.
+        CheckErrorIfEnabled(flags, {}, CScript() << OP_REVERSEBYTES,
+                            ScriptError::INVALID_STACK_OPERATION);
+
+        for (const ReverseTestCase &test_case : test_cases) {
+            CheckPassReverse(flags, test_case);
+        }
+
+        for (const valtype &palindrome : palindromes) {
+            // Verify palindrome.
+            CheckPassIfEnabled(
+                flags, {palindrome},
+                CScript() << OP_DUP << OP_REVERSEBYTES << OP_EQUALVERIFY, {});
+        }
+
+        // Verify non-palindrome fails.
+        CheckErrorIfEnabled(flags, {{0x01, 0x02, 0x03, 0x02, 0x02}},
+                            CScript()
+                                << OP_DUP << OP_REVERSEBYTES << OP_EQUALVERIFY,
+                            ScriptError::EQUALVERIFY);
+    }
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp
--- a/src/test/script_tests.cpp
+++ b/src/test/script_tests.cpp
@@ -185,7 +185,7 @@
         // anything about what happens when they are flipped. Keep them as-is.
         extra_flags &=
             ~(SCRIPT_ENABLE_SIGHASH_FORKID | SCRIPT_ENABLE_REPLAY_PROTECTION |
-              SCRIPT_ENABLE_SCHNORR_MULTISIG);
+              SCRIPT_ENABLE_SCHNORR_MULTISIG | SCRIPT_ENABLE_OP_REVERSEBYTES);
         uint32_t combined_flags =
             expect ? (flags & ~extra_flags) : (flags | extra_flags);
         // Weed out invalid flag combinations.
diff --git a/src/test/scriptflags.cpp b/src/test/scriptflags.cpp
--- a/src/test/scriptflags.cpp
+++ b/src/test/scriptflags.cpp
@@ -34,6 +34,7 @@
     {"DISALLOW_SEGWIT_RECOVERY", SCRIPT_DISALLOW_SEGWIT_RECOVERY},
     {"SCHNORR_MULTISIG", SCRIPT_ENABLE_SCHNORR_MULTISIG},
     {"INPUT_SIGCHECKS", SCRIPT_VERIFY_INPUT_SIGCHECKS},
+    {"REVERSEBYTES", SCRIPT_ENABLE_OP_REVERSEBYTES},
 };
 
 uint32_t ParseScriptFlags(std::string strFlags) {
diff --git a/test/functional/test_framework/script.py b/test/functional/test_framework/script.py
--- a/test/functional/test_framework/script.py
+++ b/test/functional/test_framework/script.py
@@ -242,6 +242,9 @@
 OP_CHECKDATASIG = CScriptOp(0xba)
 OP_CHECKDATASIGVERIFY = CScriptOp(0xbb)
 
+# additional byte string operations
+OP_REVERSEBYTES = CScriptOp(0xbc)
+
 # multi-byte opcodes
 OP_PREFIX_BEGIN = CScriptOp(0xf0)
 OP_PREFIX_END = CScriptOp(0xf7)