diff --git a/doc/src/sgml/ref/pgbench.sgml b/doc/src/sgml/ref/pgbench.sgml
index 09af9f1a7d..6ff557b2b3 100644
--- a/doc/src/sgml/ref/pgbench.sgml
+++ b/doc/src/sgml/ref/pgbench.sgml
@@ -347,7 +347,8 @@ pgbench <optional> <replaceable>options</replaceable> </optional> <replaceable>d
         An optional integer weight after <literal>@</literal> allows to adjust the
         probability of drawing the script.  If not specified, it is set to 1.
         Available built-in scripts are: <literal>tpcb-like</literal>,
-        <literal>simple-update</literal> and <literal>select-only</literal>.
+        <literal>simple-update</literal>, <literal>select-only</literal> and
+        <literal>standard-tpcb</literal>.
         Unambiguous prefixes of built-in names are accepted.
         With special name <literal>list</literal>, show the list of built-in scripts
         and exit immediately.
@@ -869,6 +870,25 @@ pgbench <optional> <replaceable>options</replaceable> </optional> <replaceable>d
    If you select the <literal>select-only</literal> built-in (also <option>-S</option>),
    only the <command>SELECT</command> is issued.
   </para>
+
+  <para>
+   If you select the <literal>standard-tpcb</literal> built-in, the SQL commands are similar
+   to <literal>tpcb-like</literal>, but the <literal>delta</literal> amount is 6 digits,
+   the account branch has a 85% probability of being in the same branch as the teller (unless
+   there is only one branch in which case it is always the same), and the final account
+   balance is actually extracted by the script.
+  </para>
+
+  <note>
+   <para>
+    Disclaimer: with <literal>standard-tpcb</literal>, only the transaction script
+    is expected to conform to the "TPC Benchmark(tm) B revision 2.0" specification.
+    Other parts of the benchmark, such as type capabilities, initialization,
+    performance data collection, checks on final values, database configuration,
+    test duration... may or may not conform to the standard depending on the actual
+    run.
+   </para>
+  </note>
  </refsect2>
 
  <refsect2>
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 8b84658ccd..4888beb129 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -193,8 +193,12 @@ int64		random_seed = -1;
  * end of configurable parameters
  *********************************************************************/
 
-#define nbranches	1			/* Makes little sense to change this.  Change
-								 * -s instead */
+/*
+ * It makes little sense to change "nbranches", use -s instead.
+ *
+ * Nevertheless, "ntellers" and "naccounts" must be divisible by "nbranches".
+ */
+#define nbranches	1
 #define ntellers	10
 #define naccounts	100000
 
@@ -566,6 +570,61 @@ static const BuiltinScript builtin_script[] =
 		"<builtin: select only>",
 		"\\set aid random(1, " CppAsString2(naccounts) " * :scale)\n"
 		"SELECT abalance FROM pgbench_accounts WHERE aid = :aid;\n"
+	},
+	{
+		/*---
+		 * Standard conforming TPC-B benchmark script as defined in
+		 * "TPC BENCHMARK (tm) B Standard Specification Revision 2.0"
+		 * from 7 June 1994, see http://www.tpc.org/tpcb/spec/tpcb_current.pdf
+		 *
+		 * The transaction profile is defined Section 1.2.
+		 *
+		 * Transaction inputs are defined in Section 5.3:
+		 *
+		 * - The account branch has a 85% probability of being in the same
+		 *   branch as the teller.
+		 * - The delta amount is in [-999999, 999999].
+		 *
+		 * By application of very explicit Section 1.3.2, the final account
+		 * balance is actually extracted by the driver with \gset.
+		 *
+		 * DISCLAIMER: only the transaction script is expected to conform to the
+		 * specification. Other parts (types capabilities, initialization,
+		 * performance data collection, database configuration, checks on final
+		 * values, ...) may or may not conform to the requirements of the
+		 * benchmark depending on the actual benchmark run.
+		 */
+		"standard-tpcb",
+		"<builtin: standard TPC-B>",
+		/* choose teller and compute its branch */
+		"\\set tid random(1, " CppAsString2(ntellers) " * :scale)\n"
+		"\\set btid 1 + (:tid - 1) / (" CppAsString2(ntellers) " / " CppAsString2(nbranches) ")\n"
+		/* choose account branch: 85% same as teller unless there is only one branch */
+		"\\if random(0, 99) < 85 or :scale * " CppAsString2(nbranches)" = 1\n"
+		"\\set bid :btid\n"
+		"\\else\n"
+		"\\set bid random(1, " CppAsString2(nbranches) " * :scale - 1)\n"
+		"\\set bid :bid + case when :bid >= :btid then 1 else 0 end\n"
+		"\\endif\n"
+		/* choose account within branch */
+		"\\set lid random(1, " CppAsString2(naccounts) "/" CppAsString2(nbranches) ")\n"
+		"\\set aid (:bid - 1) * " CppAsString2(naccounts) "/" CppAsString2(nbranches) " + :lid\n"
+		"\\set delta random(-999999, 999999)\n"
+		/* it should probably be combined, but that currently breaks -M prepared */
+		"BEGIN;\n"
+		"INSERT INTO pgbench_history (tid, bid, aid, delta, mtime)\n"
+		"  VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);\n"
+		"UPDATE pgbench_accounts\n"
+		"  SET abalance = abalance + :delta\n"
+		"  WHERE aid = :aid\n"
+		"  RETURNING abalance\\gset\n"
+		"UPDATE pgbench_tellers\n"
+		"  SET tbalance = tbalance + :delta\n"
+		"  WHERE tid = :tid;\n"
+		"UPDATE pgbench_branches\n"
+		"  SET bbalance = bbalance + :delta\n"
+		"  WHERE bid = :bid;\n"
+		"END;\n"
 	}
 };
 
@@ -3616,6 +3675,11 @@ initCreateTables(PGconn *con)
 	 * would completely break comparability of pgbench results with prior
 	 * versions. Since pgbench has never pretended to be fully TPC-B compliant
 	 * anyway, we stick with the historical behavior.
+	 *
+	 * Note 2: also according to spec, balances must hold 10 decimal digits
+	 * plus sign.  The 4-bytes "int" type used below does not conform.  Given
+	 * the default settings and the random walk (aka Drunkard's Walk) theorem,
+	 * some balances may overflow on long runs.
 	 */
 	struct ddlinfo
 	{
diff --git a/src/bin/pgbench/t/001_pgbench_with_server.pl b/src/bin/pgbench/t/001_pgbench_with_server.pl
index 3b097a91b2..db236ef5db 100644
--- a/src/bin/pgbench/t/001_pgbench_with_server.pl
+++ b/src/bin/pgbench/t/001_pgbench_with_server.pl
@@ -171,6 +171,22 @@ pgbench(
 	],
 	'pgbench select only');
 
+pgbench(
+	'-t 10 -c 3 -M prepared -b st -r',
+	0,
+	[
+		qr{builtin: standard TPC-B},
+		qr{clients: 3\b},
+		qr{threads: 1\b},
+		qr{processed: 30/30},
+		qr{mode: prepared},
+		qr{\\if random\(0, 99\) < 85}
+	],
+	[
+		qr{vacuum}
+	],
+	'pgbench standard tpc-b');
+
 # check if threads are supported
 my $nthreads = 2;
 
